<?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=Frenzzy</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=Frenzzy"/>
	<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/Special:Contributions/Frenzzy"/>
	<updated>2026-04-19T10:16:52Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.31.6</generator>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Counter-Strike:_Source_Weapons&amp;diff=8349</id>
		<title>Counter-Strike: Source Weapons</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Counter-Strike:_Source_Weapons&amp;diff=8349"/>
		<updated>2011-11-03T13:25:23Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Entity Names for Weapons ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
glock&lt;br /&gt;
usp&lt;br /&gt;
p228&lt;br /&gt;
deagle &lt;br /&gt;
elite &lt;br /&gt;
fiveseven &lt;br /&gt;
m3 &lt;br /&gt;
xm1014&lt;br /&gt;
galil &lt;br /&gt;
ak47 &lt;br /&gt;
scout &lt;br /&gt;
sg552 &lt;br /&gt;
awp &lt;br /&gt;
g3sg1 &lt;br /&gt;
famas &lt;br /&gt;
m4a1 &lt;br /&gt;
aug &lt;br /&gt;
sg550 &lt;br /&gt;
mac10 &lt;br /&gt;
tmp &lt;br /&gt;
mp5navy &lt;br /&gt;
ump45 &lt;br /&gt;
p90 &lt;br /&gt;
m249&lt;br /&gt;
vest &lt;br /&gt;
vesthelm &lt;br /&gt;
flashbang &lt;br /&gt;
hegrenade &lt;br /&gt;
smokegrenade &lt;br /&gt;
defuser &lt;br /&gt;
nvgs&lt;br /&gt;
c4&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Item Names for Weapons(GivePlayerItem)==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
weapon_glock&lt;br /&gt;
weapon_usp&lt;br /&gt;
weapon_p228&lt;br /&gt;
weapon_deagle &lt;br /&gt;
weapon_elite &lt;br /&gt;
weapon_fiveseven &lt;br /&gt;
weapon_m3 &lt;br /&gt;
weapon_xm1014 &lt;br /&gt;
weapon_galil &lt;br /&gt;
weapon_ak47 &lt;br /&gt;
weapon_scout &lt;br /&gt;
weapon_sg552 &lt;br /&gt;
weapon_awp &lt;br /&gt;
weapon_g3sg1 &lt;br /&gt;
weapon_famas &lt;br /&gt;
weapon_m4a1 &lt;br /&gt;
weapon_aug &lt;br /&gt;
weapon_sg550 &lt;br /&gt;
weapon_mac10 &lt;br /&gt;
weapon_tmp &lt;br /&gt;
weapon_mp5navy &lt;br /&gt;
weapon_ump45 &lt;br /&gt;
weapon_p90 &lt;br /&gt;
weapon_m249&lt;br /&gt;
//vest &lt;br /&gt;
item_assaultsuit //vest+helm &lt;br /&gt;
weapon_flashbang &lt;br /&gt;
weapon_hegrenade &lt;br /&gt;
weapon_smokegrenade &lt;br /&gt;
item_defuser &lt;br /&gt;
//nvgs&lt;br /&gt;
weapon_c4&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
enum WeaponType&lt;br /&gt;
{&lt;br /&gt;
    Weapon_Glock = 0,&lt;br /&gt;
    weapon_USP,&lt;br /&gt;
    Weapon_P228,&lt;br /&gt;
    Weapon_Deagle,&lt;br /&gt;
    Weapon_Elite,&lt;br /&gt;
    Weapon_FiveSeven,&lt;br /&gt;
    Weapon_M3,&lt;br /&gt;
    Weapon_XM1014,&lt;br /&gt;
    Weapon_Galil,&lt;br /&gt;
    Weapon_AK47,&lt;br /&gt;
    Weapon_Scout,&lt;br /&gt;
    Weapon_SG552,&lt;br /&gt;
    Weapon_AWP,&lt;br /&gt;
    Weapon_G3SG1,&lt;br /&gt;
    Weapon_Famas,&lt;br /&gt;
    Weapon_M4A1,&lt;br /&gt;
    Weapon_Aug,&lt;br /&gt;
    Weapon_SG550,&lt;br /&gt;
    Weapon_Mac10,&lt;br /&gt;
    Weapon_TMP,&lt;br /&gt;
    Weapon_MP5Navy,&lt;br /&gt;
    Weapon_Ump45,&lt;br /&gt;
    Weapon_P90,&lt;br /&gt;
    Weapon_M249,&lt;br /&gt;
    Weapon_Vest,&lt;br /&gt;
    Weapon_VestHelm,&lt;br /&gt;
    Weapon_FlashBang,&lt;br /&gt;
    Weapon_HEGrenade,&lt;br /&gt;
    Weapon_SmokeGrenade,&lt;br /&gt;
    Weapon_Defuser,&lt;br /&gt;
    Weapon_NightVision,&lt;br /&gt;
    Weapon_C4&lt;br /&gt;
    Weapon_Max&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=8121</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=8121"/>
		<updated>2011-06-25T18:10:32Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Python и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют шесть видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''static''': The scope of this function is restricted to the current file, can be used in combination with stock.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые SourceMod. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примечание:  String manipulation routines may be found in the string.inc file located in the include subdirectory.  They may be browsed through the [http://docs.sourcemod.net/api/ API Reference] as well.&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Обратите внимание, что &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; переменную инициализировать явно, но '''ТОЛЬКО''' как строку:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, any other tag will fail to compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl Float:blah[512] = {1.0};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
Ключевое слово &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; входит в глобальную и локальную область действия. Оно имеет различные значения в каждой из них.&lt;br /&gt;
&lt;br /&gt;
===Глобальный static===&lt;br /&gt;
Глобальные static переменные могут быть доступны только в рамках того же файла. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если плагин включает в себя оба этих файла, он не сможет использовать &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. Это простой механизм сокрытия информации, и аналогичен элементам объявления переменных, например &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; в таких языках, как C++, Java, или C#.&lt;br /&gt;
&lt;br /&gt;
===Локальный static===&lt;br /&gt;
Локальная static переменная является глобальной переменной, которая является видимой лишь из её местной области действия. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; технически глобальная переменная -- она инициализируется один раз как -1 и никогда не инициализируется заново. Оно не существует в наборе. Это означает, что при каждом запуске функции &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt;, переменная &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; и ее хранение в памяти одно и тоже.&lt;br /&gt;
&lt;br /&gt;
Возьмем следающий пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; может быть &amp;lt;tt&amp;gt;-1 +5 +6 +10&amp;lt;/tt&amp;gt;, или &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, поскольку она сохраняется за рамками этой функции. Это может создавать проблемы для рекурсивной функции: если ваша функция может быть рекурсивной, то &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;, как правило, не является хорошей идеей, если только Ваш код не реентерабельный.&lt;br /&gt;
&lt;br /&gt;
Преимуществом локальных static переменных является то, что Вам не придется загромождать свой сценарий глобальными переменными. До тех пор, пока переменной не нужно читать другую функцию, Вы можете его пихать внутрь функции и её сохранение будет гарантировано.&lt;br /&gt;
&lt;br /&gt;
Заметим, что statics может существовать в любой локальной области действия:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6782</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6782"/>
		<updated>2008-12-30T12:56:59Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Client and Entity Indexes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Отображение активности, логирование=&lt;br /&gt;
Почти все команды администратора должны логировать (записывать в лог) их активность, а некоторые команды администратора должны отобразить свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Групповые цели=&lt;br /&gt;
Чтобы полностью завершить нашу демонстрацию slap, давайте сделаем поддержку нескольких целей. [[Admin_Commands_%28SourceMod%29#How_to_Target|Targeting system]] в SourceMod достаточно усовершенствована, её использование может показаться сложным на первый взгляд.&lt;br /&gt;
&lt;br /&gt;
Мы используем функцию [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()]. Он принимает ввод с консоли, и возвращает список подходящих клиентов. Она также возвращает существительное, которые будет определять либо одного клиента или характеризовать список клиентов. Идея заключается в том, что каждый клиент будет обработан, но активность будет показана всем игрокам только один раз. Это уменьшит спам на экране.&lt;br /&gt;
&lt;br /&gt;
Этот метод обработки цели используется почти каждой командой администратора в SourceMod, а на самом деле FindTarget() является лишь упрощенной версией.&lt;br /&gt;
&lt;br /&gt;
Полный, окончательный пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - сохраняет существительные установленной цели(ей)&lt;br /&gt;
	 * target_list - массив для хранения клиентов&lt;br /&gt;
	 * target_count - переменная для хранения числа клиентов&lt;br /&gt;
	 * tn_is_ml - сохраняет должно ли существительное быть переведено&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Разрешено только живым игрокам */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* Эта функция отвечает администратору сообщение о неудачи */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Клиентский и объектный индексы=&lt;br /&gt;
Одним основным вопросом путаницы с Half-Life 2 является разница между следующими вещами:&lt;br /&gt;
*Индекс клиента (Client index)&lt;br /&gt;
*Индекс объекта (Entity index)&lt;br /&gt;
*Идентификатор пользователя (Userid)&lt;br /&gt;
&lt;br /&gt;
Первый ответ заключается в том, что клиенты это объекты. Таким образом, индекс клиента и индекс объекта одно и тоже. Когда SourceMod функция запрашивает индекс объекта, индекс клиента может быть указан. Когда SourceMod функция запрашивает индекс клиента, как правило, это означает, что только индекс клиента может быть указан.&lt;br /&gt;
&lt;br /&gt;
Быстрый способ проверить является ли индекс объекта клиентом - проверить находится ли он между 1 и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (включительно). Если сервер имеет максимум N клиентских слотов, то объекты с 1 по N, всегда зарезервированы для клиентов. Заметим, что 0 - верный индекс объекта; он является общим объектом (worldspawn).&lt;br /&gt;
&lt;br /&gt;
Идентификатор пользователя, это абсолютно другое. Сервер поддерживает общее &amp;quot;число соединений&amp;quot;, и оно начинается с 1. Каждый раз, когда подключается новый клиент, общее число соединений увеличивается, и клиент получает новый номер, называемый идентификатором пользователя.&lt;br /&gt;
&lt;br /&gt;
Например, первый подключившийся клиент имеет идентификатор пользователя 2. Если он вышел и соединился заново, его идентификатор будет 3 (если другие клиенты не подключились в этот период). Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed.&lt;br /&gt;
&lt;br /&gt;
SourceMod предусматривает две функции для userid: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Продолжение обучения=&lt;br /&gt;
Для дальнейшего обучения, смотри раздел &amp;quot;Scripting&amp;quot; в [[Ru:SourceMod Documentation]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6781</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6781"/>
		<updated>2008-12-30T12:07:42Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Further Reading */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Отображение активности, логирование=&lt;br /&gt;
Почти все команды администратора должны логировать (записывать в лог) их активность, а некоторые команды администратора должны отобразить свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Групповые цели=&lt;br /&gt;
Чтобы полностью завершить нашу демонстрацию slap, давайте сделаем поддержку нескольких целей. [[Admin_Commands_%28SourceMod%29#How_to_Target|Targeting system]] в SourceMod достаточно усовершенствована, её использование может показаться сложным на первый взгляд.&lt;br /&gt;
&lt;br /&gt;
Мы используем функцию [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()]. Он принимает ввод с консоли, и возвращает список подходящих клиентов. Она также возвращает существительное, которые будет определять либо одного клиента или характеризовать список клиентов. Идея заключается в том, что каждый клиент будет обработан, но активность будет показана всем игрокам только один раз. Это уменьшит спам на экране.&lt;br /&gt;
&lt;br /&gt;
Этот метод обработки цели используется почти каждой командой администратора в SourceMod, а на самом деле FindTarget() является лишь упрощенной версией.&lt;br /&gt;
&lt;br /&gt;
Полный, окончательный пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - сохраняет существительные установленной цели(ей)&lt;br /&gt;
	 * target_list - массив для хранения клиентов&lt;br /&gt;
	 * target_count - переменная для хранения числа клиентов&lt;br /&gt;
	 * tn_is_ml - сохраняет должно ли существительное быть переведено&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Разрешено только живым игрокам */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* Эта функция отвечает администратору сообщение о неудачи */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Продолжение обучения=&lt;br /&gt;
Для дальнейшего обучения, смотри раздел &amp;quot;Scripting&amp;quot; в [[Ru:SourceMod Documentation]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6780</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6780"/>
		<updated>2008-12-30T12:00:30Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Multiple Targets */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Отображение активности, логирование=&lt;br /&gt;
Почти все команды администратора должны логировать (записывать в лог) их активность, а некоторые команды администратора должны отобразить свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Групповые цели=&lt;br /&gt;
Чтобы полностью завершить нашу демонстрацию slap, давайте сделаем поддержку нескольких целей. [[Admin_Commands_%28SourceMod%29#How_to_Target|Targeting system]] в SourceMod достаточно усовершенствована, её использование может показаться сложным на первый взгляд.&lt;br /&gt;
&lt;br /&gt;
Мы используем функцию [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()]. Он принимает ввод с консоли, и возвращает список подходящих клиентов. Она также возвращает существительное, которые будет определять либо одного клиента или характеризовать список клиентов. Идея заключается в том, что каждый клиент будет обработан, но активность будет показана всем игрокам только один раз. Это уменьшит спам на экране.&lt;br /&gt;
&lt;br /&gt;
Этот метод обработки цели используется почти каждой командой администратора в SourceMod, а на самом деле FindTarget() является лишь упрощенной версией.&lt;br /&gt;
&lt;br /&gt;
Полный, окончательный пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - сохраняет существительные установленной цели(ей)&lt;br /&gt;
	 * target_list - массив для хранения клиентов&lt;br /&gt;
	 * target_count - переменная для хранения числа клиентов&lt;br /&gt;
	 * tn_is_ml - сохраняет должно ли существительное быть переведено&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Разрешено только живым игрокам */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* Эта функция отвечает администратору сообщение о неудачи */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6779</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6779"/>
		<updated>2008-12-30T11:54:41Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* ConVars */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Повреждение от удара по умолчанию&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Отображение активности, логирование=&lt;br /&gt;
Почти все команды администратора должны логировать (записывать в лог) их активность, а некоторые команды администратора должны отобразить свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6778</id>
		<title>Ru:Translations (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6778"/>
		<updated>2008-12-30T11:34:58Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Использование в плагине */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
[[SourceMod]], так же как и его предшественник AMX Mod X, содержит встроенный Multi-Lingual Translation layer (&amp;quot;ML&amp;quot;). Система ML является одной из дополнительных SourceMod систем, предназначенная для повышения гибкости платформы, насколько это возможно. Она полностью поддерживает UTF-8.&lt;br /&gt;
&lt;br /&gt;
=Введение=&lt;br /&gt;
Система SourceMod ML базируется на следующих терминах:&lt;br /&gt;
*'''Языки''': Предварительно заданные языки перевода устанавливаются в &amp;lt;tt&amp;gt;configs\languages.cfg&amp;lt;/tt&amp;gt;. Если язык перевода отсутствует в этом файле, он &amp;lt;b&amp;gt;не может быть переведен&amp;lt;/b&amp;gt; до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.&lt;br /&gt;
*'''Фразы'''/'''Ключи перевода''': Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке &amp;lt;tt&amp;gt;translations&amp;lt;/tt&amp;gt;. Они называются &amp;lt;tt&amp;gt;файлы перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Переводы''': Содержат фразы текста перевода для данного языка. Они находятся в &amp;lt;tt&amp;gt;файлах перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Переводы и Фразы, чувствительны к регистру.&lt;br /&gt;
&lt;br /&gt;
==Формат файла==&lt;br /&gt;
Многоязычный формат файлов перевода содержится в стандартной конфигурационной форме от Valve. Она состоит из одного главного раздела, &amp;lt;tt&amp;gt;&amp;quot;Phrases&amp;quot;&amp;lt;/tt&amp;gt;, который содержит любое число имен подразделов. Каждый подраздел определяется одним именем &amp;lt;tt&amp;gt;Фразы&amp;lt;/tt&amp;gt;, и не могут иметь в себе подразделы. Они обладают следующими свойствами:&lt;br /&gt;
*'''Ключ''': &amp;quot;#format&amp;quot;&lt;br /&gt;
**'''Значение''': Разделенные запятыми, пары индексов и форматов&lt;br /&gt;
*'''Ключ''': Двух символьный код языка.&lt;br /&gt;
**'''Значение''': Языковой перевод строки.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Welcome&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Welcome to SourceMod&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Добро пожаловать в SourceMod&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, два перевода определяется по имени фразы &amp;quot;Welcome&amp;quot; - одна для английского, и одна для русского языка. Вместе с тем, рассмотрим фразу, которая может вставлять определенные слова, как в этом примере:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Pants&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;pants&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;трусы&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//НЕПРАВИЛЬНЫЙ ПРИМЕР: &amp;quot;Frenzzy трусы горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;%s's %s are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;%s %s горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном Выше примере, порядок слов изменился. Фраза на английском вставляет объект первым, а фраза на русском предписывает объект вторым. На русском языке фраза должна выглядеть следующим образом: ''Трусы Frenzzy горят!''. Это создает проблему для скриптов, которые всегда просматривают формат параметров в одном порядке. Чтобы решить эту проблему, было введено свойство &amp;lt;tt&amp;gt;#format&amp;lt;/tt&amp;gt;. Оно предопределяет порядок формата параметров. Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	//Пример: &amp;quot;Трусы Frenzzy горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s},{2:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;{1}'s {2} are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;{2} {1} горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//Пример: &amp;quot;Привет, Frenzzy!&amp;quot;&lt;br /&gt;
	&amp;quot;Hello&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Hello, {1}&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Привет, {1}&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат строки состоит из разделов которые разделяются запятыми, а каждый раздел заключен в скобках. Каждый раздел имеет ''индекс'' и ''спецификатор формата'', которые разделяются двоеточиями. Спецификаторы формата следуют общим правилам [[Ru:Format Class Functions (SourceMod Scripting)|форматирования]], однако в настоящее время, они поддерживаются только в следующих видах:&lt;br /&gt;
*'''d'''/'''i''': Отображение десятичных/целых значений&lt;br /&gt;
*'''x''': Отображение шестнадцатеричных значений&lt;br /&gt;
*'''f''': Отображение числа с плавающей точкой&lt;br /&gt;
*'''s''': Отображение строки&lt;br /&gt;
*'''c''': Отображение символов (поддерживается UTF-8)&lt;br /&gt;
&lt;br /&gt;
Заметим, что в настоящее время специальный формат типа &amp;quot;%T&amp;quot; не допускает внутри языка перевод строки.&lt;br /&gt;
&lt;br /&gt;
=Использование в плагине=&lt;br /&gt;
Плагины должны вызывать функцию &amp;lt;tt&amp;gt;LoadTranslations&amp;lt;/tt&amp;gt; на каждый файл с переводом, который они хотят использовать. Если это не будет сделано, то никакие переводы работать не будут, даже если другой плагин загрузил те же самые файлы. Это поможет предотвратить конфликты фраз между плагинами.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': языковые файлы загружаться после каждой смены карты (mapchange). Даже если плагин будет перезагружен, кэшированный перевод файлов остается до следующей карты.&lt;br /&gt;
&lt;br /&gt;
Встроенный перевод работает в любых [[Ru:Format Class Functions (SourceMod Scripting)|формат-классовых]] функциях. Вводится новый спецификатор формата '%T', который указывает формат вставки определенного перевода фразы. В отличие от всех других спецификаторов формата, он требует как минимум двух параметров:&lt;br /&gt;
*'''1-ый параметр''': Строка, содержащая фразу для перевода.&lt;br /&gt;
*'''2-ой параметр''': Одно из следующих:&lt;br /&gt;
**Постоянная &amp;lt;tt&amp;gt;LANG_SERVER&amp;lt;/tt&amp;gt;, которая определяет язык перевода по умолчанию.&lt;br /&gt;
**Константа player ID, которая определяет язык перевода установленный игроком.&lt;br /&gt;
*'''3-ий параметр и больше''': Вывод во фразе спецификаторов формата, если это необходимо.&lt;br /&gt;
&lt;br /&gt;
Примерами являются:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:name[32], String:buffer[128];&lt;br /&gt;
GetClientName(client, name, sizeof(name));&lt;br /&gt;
PrintToChat(client, &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, client, name);&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, LANG_SERVER, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат параметров в отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;Hello&amp;quot;&amp;lt;/tt&amp;gt;: Фраза для перевода.&lt;br /&gt;
*&amp;lt;tt&amp;gt;client/LANG_SERVER&amp;lt;/tt&amp;gt;: Кто получит перевод фразы.&lt;br /&gt;
*&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;: The &amp;quot;Hello&amp;quot; phrase requires one string, so this will appear in the translated phrase.&lt;br /&gt;
&lt;br /&gt;
Наконец, существует вторая форма однострочного перевода, используя '%t'. Она допускается только в функциях, которые действуют непосредственно на одного или нескольких клиентов. Она исключает второй параметр, и использует указанного клиента. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(client, &amp;quot;[SourceMod] %t&amp;quot;, &amp;quot;Hello&amp;quot;, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как видно из этого примера, Мы не должны указывать индекс клиента больше, чем один раз. Таким образом, как правило, более удобны для использования ограниченные версии '%t' в функциях, таких как &amp;lt;tt&amp;gt;PrintToChat&amp;lt;/tt&amp;gt;. Однако, в функциях, которые не &amp;quot;управляют игроком&amp;quot;, таких, как &amp;lt;tt&amp;gt;Format&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt;, может быть использован только '%T'.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6777</id>
		<title>Ru:Translations (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6777"/>
		<updated>2008-12-30T11:34:34Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Usage in a Plugin */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
[[SourceMod]], так же как и его предшественник AMX Mod X, содержит встроенный Multi-Lingual Translation layer (&amp;quot;ML&amp;quot;). Система ML является одной из дополнительных SourceMod систем, предназначенная для повышения гибкости платформы, насколько это возможно. Она полностью поддерживает UTF-8.&lt;br /&gt;
&lt;br /&gt;
=Введение=&lt;br /&gt;
Система SourceMod ML базируется на следующих терминах:&lt;br /&gt;
*'''Языки''': Предварительно заданные языки перевода устанавливаются в &amp;lt;tt&amp;gt;configs\languages.cfg&amp;lt;/tt&amp;gt;. Если язык перевода отсутствует в этом файле, он &amp;lt;b&amp;gt;не может быть переведен&amp;lt;/b&amp;gt; до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.&lt;br /&gt;
*'''Фразы'''/'''Ключи перевода''': Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке &amp;lt;tt&amp;gt;translations&amp;lt;/tt&amp;gt;. Они называются &amp;lt;tt&amp;gt;файлы перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Переводы''': Содержат фразы текста перевода для данного языка. Они находятся в &amp;lt;tt&amp;gt;файлах перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Переводы и Фразы, чувствительны к регистру.&lt;br /&gt;
&lt;br /&gt;
==Формат файла==&lt;br /&gt;
Многоязычный формат файлов перевода содержится в стандартной конфигурационной форме от Valve. Она состоит из одного главного раздела, &amp;lt;tt&amp;gt;&amp;quot;Phrases&amp;quot;&amp;lt;/tt&amp;gt;, который содержит любое число имен подразделов. Каждый подраздел определяется одним именем &amp;lt;tt&amp;gt;Фразы&amp;lt;/tt&amp;gt;, и не могут иметь в себе подразделы. Они обладают следующими свойствами:&lt;br /&gt;
*'''Ключ''': &amp;quot;#format&amp;quot;&lt;br /&gt;
**'''Значение''': Разделенные запятыми, пары индексов и форматов&lt;br /&gt;
*'''Ключ''': Двух символьный код языка.&lt;br /&gt;
**'''Значение''': Языковой перевод строки.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Welcome&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Welcome to SourceMod&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Добро пожаловать в SourceMod&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, два перевода определяется по имени фразы &amp;quot;Welcome&amp;quot; - одна для английского, и одна для русского языка. Вместе с тем, рассмотрим фразу, которая может вставлять определенные слова, как в этом примере:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Pants&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;pants&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;трусы&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//НЕПРАВИЛЬНЫЙ ПРИМЕР: &amp;quot;Frenzzy трусы горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;%s's %s are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;%s %s горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном Выше примере, порядок слов изменился. Фраза на английском вставляет объект первым, а фраза на русском предписывает объект вторым. На русском языке фраза должна выглядеть следующим образом: ''Трусы Frenzzy горят!''. Это создает проблему для скриптов, которые всегда просматривают формат параметров в одном порядке. Чтобы решить эту проблему, было введено свойство &amp;lt;tt&amp;gt;#format&amp;lt;/tt&amp;gt;. Оно предопределяет порядок формата параметров. Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	//Пример: &amp;quot;Трусы Frenzzy горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s},{2:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;{1}'s {2} are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;{2} {1} горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//Пример: &amp;quot;Привет, Frenzzy!&amp;quot;&lt;br /&gt;
	&amp;quot;Hello&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Hello, {1}&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Привет, {1}&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат строки состоит из разделов которые разделяются запятыми, а каждый раздел заключен в скобках. Каждый раздел имеет ''индекс'' и ''спецификатор формата'', которые разделяются двоеточиями. Спецификаторы формата следуют общим правилам [[Ru:Format Class Functions (SourceMod Scripting)|форматирования]], однако в настоящее время, они поддерживаются только в следующих видах:&lt;br /&gt;
*'''d'''/'''i''': Отображение десятичных/целых значений&lt;br /&gt;
*'''x''': Отображение шестнадцатеричных значений&lt;br /&gt;
*'''f''': Отображение числа с плавающей точкой&lt;br /&gt;
*'''s''': Отображение строки&lt;br /&gt;
*'''c''': Отображение символов (поддерживается UTF-8)&lt;br /&gt;
&lt;br /&gt;
Заметим, что в настоящее время специальный формат типа &amp;quot;%T&amp;quot; не допускает внутри языка перевод строки.&lt;br /&gt;
&lt;br /&gt;
=Использование в плагине=&lt;br /&gt;
Плагины должны вызывать функцию &amp;lt;tt&amp;gt;LoadTranslations&amp;lt;/tt&amp;gt; на каждый файл с переводом, который они хотят использовать. Если это не будет сделано, то никакие переводы работать не будут, даже если другой плагин загрузил те же самые файлы. Это поможет предотвратить конфликты фраз между плагинами.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': языковые файлы загружаться после каждой смены карты (mapchange). Даже если плагин будет перезагружен, кэшированный перевод файлов остается до следующей карты.&lt;br /&gt;
&lt;br /&gt;
Встроенный перевод работает в любых [[Ru:Format Class Functions (SourceMod Scripting)|формат-классовых]] функциях. Вводится новый спецификатор формата '%T', который указывает формат вставки определенного перевода фразы. В отличие от всех других спецификаторов формата, он требует как минимум двух параметров:&lt;br /&gt;
*'''1-ый параметр''': Строка, содержащая фразу для перевода.&lt;br /&gt;
*'''2-ой параметр''': Одно из следующих:&lt;br /&gt;
**Постоянная &amp;lt;tt&amp;gt;LANG_SERVER&amp;lt;/tt&amp;gt;, которая определяет язык перевода по умолчанию.&lt;br /&gt;
**Константа player ID, которая определяет язык перевода установленный игроком.&lt;br /&gt;
*'''3-ий параметр и выше''': Вывод во фразе спецификаторов формата, если это необходимо.&lt;br /&gt;
&lt;br /&gt;
Примерами являются:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:name[32], String:buffer[128];&lt;br /&gt;
GetClientName(client, name, sizeof(name));&lt;br /&gt;
PrintToChat(client, &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, client, name);&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, LANG_SERVER, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат параметров в отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;Hello&amp;quot;&amp;lt;/tt&amp;gt;: Фраза для перевода.&lt;br /&gt;
*&amp;lt;tt&amp;gt;client/LANG_SERVER&amp;lt;/tt&amp;gt;: Кто получит перевод фразы.&lt;br /&gt;
*&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;: The &amp;quot;Hello&amp;quot; phrase requires one string, so this will appear in the translated phrase.&lt;br /&gt;
&lt;br /&gt;
Наконец, существует вторая форма однострочного перевода, используя '%t'. Она допускается только в функциях, которые действуют непосредственно на одного или нескольких клиентов. Она исключает второй параметр, и использует указанного клиента. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(client, &amp;quot;[SourceMod] %t&amp;quot;, &amp;quot;Hello&amp;quot;, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как видно из этого примера, Мы не должны указывать индекс клиента больше, чем один раз. Таким образом, как правило, более удобны для использования ограниченные версии '%t' в функциях, таких как &amp;lt;tt&amp;gt;PrintToChat&amp;lt;/tt&amp;gt;. Однако, в функциях, которые не &amp;quot;управляют игроком&amp;quot;, таких, как &amp;lt;tt&amp;gt;Format&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt;, может быть использован только '%T'.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6776</id>
		<title>Ru:Translations (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6776"/>
		<updated>2008-12-30T10:50:06Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Формат файла */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
[[SourceMod]], так же как и его предшественник AMX Mod X, содержит встроенный Multi-Lingual Translation layer (&amp;quot;ML&amp;quot;). Система ML является одной из дополнительных SourceMod систем, предназначенная для повышения гибкости платформы, насколько это возможно. Она полностью поддерживает UTF-8.&lt;br /&gt;
&lt;br /&gt;
=Введение=&lt;br /&gt;
Система SourceMod ML базируется на следующих терминах:&lt;br /&gt;
*'''Языки''': Предварительно заданные языки перевода устанавливаются в &amp;lt;tt&amp;gt;configs\languages.cfg&amp;lt;/tt&amp;gt;. Если язык перевода отсутствует в этом файле, он &amp;lt;b&amp;gt;не может быть переведен&amp;lt;/b&amp;gt; до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.&lt;br /&gt;
*'''Фразы'''/'''Ключи перевода''': Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке &amp;lt;tt&amp;gt;translations&amp;lt;/tt&amp;gt;. Они называются &amp;lt;tt&amp;gt;файлы перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Переводы''': Содержат фразы текста перевода для данного языка. Они находятся в &amp;lt;tt&amp;gt;файлах перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Переводы и Фразы, чувствительны к регистру.&lt;br /&gt;
&lt;br /&gt;
==Формат файла==&lt;br /&gt;
Многоязычный формат файлов перевода содержится в стандартной конфигурационной форме от Valve. Она состоит из одного главного раздела, &amp;lt;tt&amp;gt;&amp;quot;Phrases&amp;quot;&amp;lt;/tt&amp;gt;, который содержит любое число имен подразделов. Каждый подраздел определяется одним именем &amp;lt;tt&amp;gt;Фразы&amp;lt;/tt&amp;gt;, и не могут иметь в себе подразделы. Они обладают следующими свойствами:&lt;br /&gt;
*'''Ключ''': &amp;quot;#format&amp;quot;&lt;br /&gt;
**'''Значение''': Разделенные запятыми, пары индексов и форматов&lt;br /&gt;
*'''Ключ''': Двух символьный код языка.&lt;br /&gt;
**'''Значение''': Языковой перевод строки.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Welcome&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Welcome to SourceMod&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Добро пожаловать в SourceMod&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, два перевода определяется по имени фразы &amp;quot;Welcome&amp;quot; - одна для английского, и одна для русского языка. Вместе с тем, рассмотрим фразу, которая может вставлять определенные слова, как в этом примере:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Pants&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;pants&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;трусы&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//НЕПРАВИЛЬНЫЙ ПРИМЕР: &amp;quot;Frenzzy трусы горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;%s's %s are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;%s %s горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном Выше примере, порядок слов изменился. Фраза на английском вставляет объект первым, а фраза на русском предписывает объект вторым. На русском языке фраза должна выглядеть следующим образом: ''Трусы Frenzzy горят!''. Это создает проблему для скриптов, которые всегда просматривают формат параметров в одном порядке. Чтобы решить эту проблему, было введено свойство &amp;lt;tt&amp;gt;#format&amp;lt;/tt&amp;gt;. Оно предопределяет порядок формата параметров. Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	//Пример: &amp;quot;Трусы Frenzzy горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s},{2:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;{1}'s {2} are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;{2} {1} горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//Пример: &amp;quot;Привет, Frenzzy!&amp;quot;&lt;br /&gt;
	&amp;quot;Hello&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Hello, {1}&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Привет, {1}&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат строки состоит из разделов которые разделяются запятыми, а каждый раздел заключен в скобках. Каждый раздел имеет ''индекс'' и ''спецификатор формата'', которые разделяются двоеточиями. Спецификаторы формата следуют общим правилам [[Ru:Format Class Functions (SourceMod Scripting)|форматирования]], однако в настоящее время, они поддерживаются только в следующих видах:&lt;br /&gt;
*'''d'''/'''i''': Отображение десятичных/целых значений&lt;br /&gt;
*'''x''': Отображение шестнадцатеричных значений&lt;br /&gt;
*'''f''': Отображение числа с плавающей точкой&lt;br /&gt;
*'''s''': Отображение строки&lt;br /&gt;
*'''c''': Отображение символов (поддерживается UTF-8)&lt;br /&gt;
&lt;br /&gt;
Заметим, что в настоящее время специальный формат типа &amp;quot;%T&amp;quot; не допускает внутри языка перевод строки.&lt;br /&gt;
&lt;br /&gt;
=Usage in a Plugin=&lt;br /&gt;
Plugins must call &amp;lt;tt&amp;gt;LoadTranslations&amp;lt;/tt&amp;gt; on each translation file they wish to use.  Failure to do so will cause any translations to fail, even if another plugin loads the same file.  This is to help prevent phrase-clashes between plugins.  &lt;br /&gt;
&lt;br /&gt;
'''Note''': Language files are reloaded every mapchange. Even if the plugin gets reloaded, the translation file stays cached until next map.&lt;br /&gt;
&lt;br /&gt;
Inline translation works in any [[Format Class Functions (SourceMod Scripting)|format-class]] of functions.  A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase.  Unlike all other format specifiers, this requires a minimum of two parameters:&lt;br /&gt;
*'''1st Parameter''': A string containing the phrase to be translated.&lt;br /&gt;
*'''2nd Parameter''': One of the following:&lt;br /&gt;
**The &amp;lt;tt&amp;gt;LANG_SERVER&amp;lt;/tt&amp;gt; constant, which specifies a translation to the default language.&lt;br /&gt;
**A player ID constant, which specifies a translation to the player's set language.&lt;br /&gt;
*'''3rd Parameter and higher''': Inputs into the phrase's format specifiers, if necessary.&lt;br /&gt;
&lt;br /&gt;
Examples of this are:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:name[32], String:buffer[128];&lt;br /&gt;
GetClientName(client, name, sizeof(name));&lt;br /&gt;
PrintToChat(client, &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, client, name);&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, LANG_SERVER, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A breakdown of the format parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;Hello&amp;quot;&amp;lt;/tt&amp;gt;: The phrase to translate.&lt;br /&gt;
*&amp;lt;tt&amp;gt;client/LANG_SERVER&amp;lt;/tt&amp;gt;: Who to translate the phrase to.&lt;br /&gt;
*&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;: The &amp;quot;Hello&amp;quot; phrase requires one string, so this will appear in the translated phrase.&lt;br /&gt;
&lt;br /&gt;
Lastly, there is a second form of inline translation, using '%t'.  This is only allowed in functions which act directly on one or more clients.  It eliminates the second parameter, and uses the original client specified.  Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(client, &amp;quot;[SourceMod] %t&amp;quot;, &amp;quot;Hello&amp;quot;, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see from this example, we did not have to specify the client index more than once.  Thus, it is usually more convenient to use the limited '%t' version in functions such as &amp;lt;tt&amp;gt;PrintToChat&amp;lt;/tt&amp;gt;.  However, in functions which are not &amp;quot;player directed,&amp;quot; such as &amp;lt;tt&amp;gt;Format&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt;, only '%T' can be used.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6775</id>
		<title>Ru:Translations (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6775"/>
		<updated>2008-12-30T10:48:58Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Формат файла */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
[[SourceMod]], так же как и его предшественник AMX Mod X, содержит встроенный Multi-Lingual Translation layer (&amp;quot;ML&amp;quot;). Система ML является одной из дополнительных SourceMod систем, предназначенная для повышения гибкости платформы, насколько это возможно. Она полностью поддерживает UTF-8.&lt;br /&gt;
&lt;br /&gt;
=Введение=&lt;br /&gt;
Система SourceMod ML базируется на следующих терминах:&lt;br /&gt;
*'''Языки''': Предварительно заданные языки перевода устанавливаются в &amp;lt;tt&amp;gt;configs\languages.cfg&amp;lt;/tt&amp;gt;. Если язык перевода отсутствует в этом файле, он &amp;lt;b&amp;gt;не может быть переведен&amp;lt;/b&amp;gt; до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.&lt;br /&gt;
*'''Фразы'''/'''Ключи перевода''': Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке &amp;lt;tt&amp;gt;translations&amp;lt;/tt&amp;gt;. Они называются &amp;lt;tt&amp;gt;файлы перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Переводы''': Содержат фразы текста перевода для данного языка. Они находятся в &amp;lt;tt&amp;gt;файлах перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Переводы и Фразы, чувствительны к регистру.&lt;br /&gt;
&lt;br /&gt;
==Формат файла==&lt;br /&gt;
Многоязычный формат файлов перевода содержится в стандартной конфигурационной форме от Valve. Она состоит из одного главного раздела, &amp;lt;tt&amp;gt;&amp;quot;Phrases&amp;quot;&amp;lt;/tt&amp;gt;, который содержит любое число имен подразделов. Каждый подраздел определяется одним именем &amp;lt;tt&amp;gt;Фразы&amp;lt;/tt&amp;gt;, и не могут иметь в себе подразделы. Они обладают следующими свойствами:&lt;br /&gt;
*'''Ключ''': &amp;quot;#format&amp;quot;&lt;br /&gt;
**'''Значение''': Разделенные запятыми, пары индексов и форматов&lt;br /&gt;
*'''Ключ''': Двух символьный код языка.&lt;br /&gt;
**'''Значение''': Языковой перевод строки.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Welcome&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Welcome to SourceMod&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Добро пожаловать в SourceMod&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, два перевода определяется по имени фразы &amp;quot;Welcome&amp;quot; - одна для английского, и одна для русского языка. Вместе с тем, рассмотрим фразу, которая может вставлять определенные слова, как в этом примере:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Pants&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;pants&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;трусы&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//НЕПРАВИЛЬНЫЙ ПРИМЕР: &amp;quot;Frenzzy трусы горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;%s's %s are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;%s %s горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном Выше примере, порядок слов изменился. Фраза на английском вставляет объект первым, а фраза на русском предписывает объект вторым. На русском языке фраза должна выглядеть следующим образом: ''Трусы Frenzzy горят!''. Это создает проблему для скриптов, которые всегда просматривают формат параметров в одном порядке. Чтобы решить эту проблему, было введено свойство &amp;lt;tt&amp;gt;#format&amp;lt;/tt&amp;gt;. Оно предопределяет порядок формата параметров. Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	//Пример: &amp;quot;Frenzzy трусы горят&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s},{2:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;{1}'s {2} are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;{2} {1} горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//Пример: &amp;quot;Привет, Frenzzy!&amp;quot;&lt;br /&gt;
	&amp;quot;Hello&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Hello, {1}&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;Привет, {1}&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат строки состоит из разделов которые разделяются запятыми, а каждый раздел заключен в скобках. Каждый раздел имеет ''индекс'' и ''спецификатор формата'', которые разделяются двоеточиями. Спецификаторы формата следуют общим правилам [[Ru:Format Class Functions (SourceMod Scripting)|форматирования]], однако в настоящее время, они поддерживаются только в следующих видах:&lt;br /&gt;
*'''d'''/'''i''': Отображение десятичных/целых значений&lt;br /&gt;
*'''x''': Отображение шестнадцатеричных значений&lt;br /&gt;
*'''f''': Отображение числа с плавающей точкой&lt;br /&gt;
*'''s''': Отображение строки&lt;br /&gt;
*'''c''': Отображение символов (поддерживается UTF-8)&lt;br /&gt;
&lt;br /&gt;
Заметим, что в настоящее время специальный формат типа &amp;quot;%T&amp;quot; не допускает внутри языка перевод строки.&lt;br /&gt;
&lt;br /&gt;
=Usage in a Plugin=&lt;br /&gt;
Plugins must call &amp;lt;tt&amp;gt;LoadTranslations&amp;lt;/tt&amp;gt; on each translation file they wish to use.  Failure to do so will cause any translations to fail, even if another plugin loads the same file.  This is to help prevent phrase-clashes between plugins.  &lt;br /&gt;
&lt;br /&gt;
'''Note''': Language files are reloaded every mapchange. Even if the plugin gets reloaded, the translation file stays cached until next map.&lt;br /&gt;
&lt;br /&gt;
Inline translation works in any [[Format Class Functions (SourceMod Scripting)|format-class]] of functions.  A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase.  Unlike all other format specifiers, this requires a minimum of two parameters:&lt;br /&gt;
*'''1st Parameter''': A string containing the phrase to be translated.&lt;br /&gt;
*'''2nd Parameter''': One of the following:&lt;br /&gt;
**The &amp;lt;tt&amp;gt;LANG_SERVER&amp;lt;/tt&amp;gt; constant, which specifies a translation to the default language.&lt;br /&gt;
**A player ID constant, which specifies a translation to the player's set language.&lt;br /&gt;
*'''3rd Parameter and higher''': Inputs into the phrase's format specifiers, if necessary.&lt;br /&gt;
&lt;br /&gt;
Examples of this are:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:name[32], String:buffer[128];&lt;br /&gt;
GetClientName(client, name, sizeof(name));&lt;br /&gt;
PrintToChat(client, &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, client, name);&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, LANG_SERVER, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A breakdown of the format parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;Hello&amp;quot;&amp;lt;/tt&amp;gt;: The phrase to translate.&lt;br /&gt;
*&amp;lt;tt&amp;gt;client/LANG_SERVER&amp;lt;/tt&amp;gt;: Who to translate the phrase to.&lt;br /&gt;
*&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;: The &amp;quot;Hello&amp;quot; phrase requires one string, so this will appear in the translated phrase.&lt;br /&gt;
&lt;br /&gt;
Lastly, there is a second form of inline translation, using '%t'.  This is only allowed in functions which act directly on one or more clients.  It eliminates the second parameter, and uses the original client specified.  Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(client, &amp;quot;[SourceMod] %t&amp;quot;, &amp;quot;Hello&amp;quot;, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see from this example, we did not have to specify the client index more than once.  Thus, it is usually more convenient to use the limited '%t' version in functions such as &amp;lt;tt&amp;gt;PrintToChat&amp;lt;/tt&amp;gt;.  However, in functions which are not &amp;quot;player directed,&amp;quot; such as &amp;lt;tt&amp;gt;Format&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt;, only '%T' can be used.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6774</id>
		<title>Ru:Translations (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6774"/>
		<updated>2008-12-30T10:43:03Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Введение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
[[SourceMod]], так же как и его предшественник AMX Mod X, содержит встроенный Multi-Lingual Translation layer (&amp;quot;ML&amp;quot;). Система ML является одной из дополнительных SourceMod систем, предназначенная для повышения гибкости платформы, насколько это возможно. Она полностью поддерживает UTF-8.&lt;br /&gt;
&lt;br /&gt;
=Введение=&lt;br /&gt;
Система SourceMod ML базируется на следующих терминах:&lt;br /&gt;
*'''Языки''': Предварительно заданные языки перевода устанавливаются в &amp;lt;tt&amp;gt;configs\languages.cfg&amp;lt;/tt&amp;gt;. Если язык перевода отсутствует в этом файле, он &amp;lt;b&amp;gt;не может быть переведен&amp;lt;/b&amp;gt; до тех пор, пока не будет добавлен в этот файл и обновлена кэш-память переводов.&lt;br /&gt;
*'''Фразы'''/'''Ключи перевода''': Короткие, общие ключевые фразы, используемые для определения набора переводов. Они находятся в конфигурационных файлах в папке &amp;lt;tt&amp;gt;translations&amp;lt;/tt&amp;gt;. Они называются &amp;lt;tt&amp;gt;файлы перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Переводы''': Содержат фразы текста перевода для данного языка. Они находятся в &amp;lt;tt&amp;gt;файлах перевода&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Переводы и Фразы, чувствительны к регистру.&lt;br /&gt;
&lt;br /&gt;
==Формат файла==&lt;br /&gt;
Многоязычный формат файлов перевода содержится в стандартной конфигурационной форме от Valve. Она состоит из одного главного раздела, &amp;lt;tt&amp;gt;&amp;quot;Phrases&amp;quot;&amp;lt;/tt&amp;gt;, который содержит любое число имен подразделов. Каждый подраздел определяется одним именем &amp;lt;tt&amp;gt;Фразы&amp;lt;/tt&amp;gt;, и не могут иметь в себе подразделы. Они обладают следующими свойствами:&lt;br /&gt;
*'''Key''': &amp;quot;#format&amp;quot;&lt;br /&gt;
**'''Value''': Comma-delimited, ordered pairs of indexes and format strings.&lt;br /&gt;
*'''Key''': Two-letter language code.&lt;br /&gt;
**'''Value''': Language translation string.&lt;br /&gt;
&lt;br /&gt;
Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Welcome&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Welcome to SourceMod&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;Добро пожаловать в SourceMod&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, два перевода определяется по имени фразы &amp;quot;Welcome&amp;quot; - одна для английского, и одна для русского языка. Вместе с тем, рассмотрим фразу, которая может вставлять определенные слова, как в этом примере:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Pants&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;pants&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;трусы&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//НЕПРАВИЛЬНЫЙ ПРИМЕР: &amp;quot;Frenzzy трусы горят!&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;%s's %s are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;ru&amp;quot;		&amp;quot;%s %s горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном Выше примере, порядок слов изменился. Фраза на английском вставляет объект первым, а фраза на русском предписывает объект вторым. На русском языке фраза должна выглядеть следующим образом: ''Трусы Frenzzy горят!''. Это создает проблему для скриптов, которые всегда просматривают формат параметров в одном порядке. Чтобы решить эту проблему, было введено свойство &amp;lt;tt&amp;gt;#format&amp;lt;/tt&amp;gt;. Оно предопределяет порядок формата параметров. Пример:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	//Пример: &amp;quot;Frenzzy трусы горят&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s},{2:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;{1}'s {2} are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;{2} {1} горят!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//Пример: &amp;quot;Привет, Frenzzy!&amp;quot;&lt;br /&gt;
	&amp;quot;Hello&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Hello, {1}&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;Привет, {1}&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Формат строки состоит из разделов которые разделяются запятыми, а каждый раздел заключен в скобках. Каждый раздел имеет ''индекс'' и ''спецификатор формата'', которые разделяются двоеточиями. Спецификаторы формата следуют общим правилам [[Ru:Format Class Functions (SourceMod Scripting)|форматирования]], однако в настоящее время, они поддерживаются только в следующих видах:&lt;br /&gt;
*'''d'''/'''i''': Отображение десятичных/целых значений&lt;br /&gt;
*'''x''': Отображение шестнадцатеричных значений&lt;br /&gt;
*'''f''': Отображение числа с плавающей точкой&lt;br /&gt;
*'''s''': Отображение строки&lt;br /&gt;
*'''c''': Отображение символов (поддерживается UTF-8)&lt;br /&gt;
&lt;br /&gt;
Заметим, что в настоящее время специальный формат типа &amp;quot;%T&amp;quot; не допускает внутри языка перевод строки.&lt;br /&gt;
&lt;br /&gt;
=Usage in a Plugin=&lt;br /&gt;
Plugins must call &amp;lt;tt&amp;gt;LoadTranslations&amp;lt;/tt&amp;gt; on each translation file they wish to use.  Failure to do so will cause any translations to fail, even if another plugin loads the same file.  This is to help prevent phrase-clashes between plugins.  &lt;br /&gt;
&lt;br /&gt;
'''Note''': Language files are reloaded every mapchange. Even if the plugin gets reloaded, the translation file stays cached until next map.&lt;br /&gt;
&lt;br /&gt;
Inline translation works in any [[Format Class Functions (SourceMod Scripting)|format-class]] of functions.  A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase.  Unlike all other format specifiers, this requires a minimum of two parameters:&lt;br /&gt;
*'''1st Parameter''': A string containing the phrase to be translated.&lt;br /&gt;
*'''2nd Parameter''': One of the following:&lt;br /&gt;
**The &amp;lt;tt&amp;gt;LANG_SERVER&amp;lt;/tt&amp;gt; constant, which specifies a translation to the default language.&lt;br /&gt;
**A player ID constant, which specifies a translation to the player's set language.&lt;br /&gt;
*'''3rd Parameter and higher''': Inputs into the phrase's format specifiers, if necessary.&lt;br /&gt;
&lt;br /&gt;
Examples of this are:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:name[32], String:buffer[128];&lt;br /&gt;
GetClientName(client, name, sizeof(name));&lt;br /&gt;
PrintToChat(client, &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, client, name);&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, LANG_SERVER, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A breakdown of the format parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;Hello&amp;quot;&amp;lt;/tt&amp;gt;: The phrase to translate.&lt;br /&gt;
*&amp;lt;tt&amp;gt;client/LANG_SERVER&amp;lt;/tt&amp;gt;: Who to translate the phrase to.&lt;br /&gt;
*&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;: The &amp;quot;Hello&amp;quot; phrase requires one string, so this will appear in the translated phrase.&lt;br /&gt;
&lt;br /&gt;
Lastly, there is a second form of inline translation, using '%t'.  This is only allowed in functions which act directly on one or more clients.  It eliminates the second parameter, and uses the original client specified.  Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(client, &amp;quot;[SourceMod] %t&amp;quot;, &amp;quot;Hello&amp;quot;, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see from this example, we did not have to specify the client index more than once.  Thus, it is usually more convenient to use the limited '%t' version in functions such as &amp;lt;tt&amp;gt;PrintToChat&amp;lt;/tt&amp;gt;.  However, in functions which are not &amp;quot;player directed,&amp;quot; such as &amp;lt;tt&amp;gt;Format&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt;, only '%T' can be used.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6752</id>
		<title>Ru:Translations (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Translations_(SourceMod_Scripting)&amp;diff=6752"/>
		<updated>2008-12-28T16:31:43Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__FORCETOC__&lt;br /&gt;
[[SourceMod]], так же как и его предшественник AMX Mod X, содержит встроенный Multi-Lingual Translation layer (&amp;quot;ML&amp;quot;). Система ML является одной из дополнительных SourceMod систем, предназначенная для повышения гибкости платформы, насколько это возможно. Она полностью поддерживает UTF-8.&lt;br /&gt;
&lt;br /&gt;
=Введение=&lt;br /&gt;
The SourceMod ML System is based off the following terms:&lt;br /&gt;
*'''Languages''': Preset languages defined in &amp;lt;tt&amp;gt;configs\languages.cfg&amp;lt;/tt&amp;gt;.  If a language is not in this file, it &amp;lt;b&amp;gt;cannot be translated&amp;lt;/b&amp;gt; until it is added and the in-memory translation cache rebuilt.&lt;br /&gt;
*'''Phrases'''/'''Translation Keys''': Short, generic key phrases used to identify a set of translations.  These reside in configuration files in the &amp;lt;tt&amp;gt;translations&amp;lt;/tt&amp;gt; folder.  These are called &amp;lt;tt&amp;gt;translation files&amp;lt;/tt&amp;gt;.&lt;br /&gt;
*'''Translations''': A given text translation of a phrase for a given language.  These reside in a &amp;lt;tt&amp;gt;translation file&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
'''Note''': Languages and Phrases are both case sensitive.&lt;br /&gt;
&lt;br /&gt;
==File Format==&lt;br /&gt;
The ML Translation File format is in standard Valve configuration form.  It is comprised of one master section, &amp;lt;tt&amp;gt;&amp;quot;Phrases&amp;lt;/tt&amp;gt;,&amp;lt;tt&amp;gt;&amp;quot;&amp;lt;/tt&amp;gt; which contains any number of named sub-sections.  Each sub-section defines one named &amp;lt;tt&amp;gt;Phrase&amp;lt;/tt&amp;gt;, which cannot itself have sub-sections.  It allows the following properties:&lt;br /&gt;
*'''Key''': &amp;quot;#format&amp;quot;&lt;br /&gt;
**'''Value''': Comma-delimited, ordered pairs of indexes and format strings.&lt;br /&gt;
*'''Key''': Two-letter language code.&lt;br /&gt;
**'''Value''': Language translation string.&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Welcome&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Welcome to SourceMod&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;Bienvenidos a SourceMod&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, two translations are defined for the &amp;quot;Welcome&amp;quot; phrase - one for English, and one for Spanish.  However, consider a phrase which needs certain words inserted, as in this contrived example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;Pants&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;pants&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;pantalones&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//INVALID EXAMPLE: &amp;quot;Bail's pants are on fire&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;%s's %s are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;¡Los %s de %s están en llamas!&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, the word orders have changed.  English inserts the subject first, and the direct object second.  Spanish associates ownership differently -- literally, ''the pants of Bail are on fire.''  This poses a problem for scripters, who always pass format parameters in one order.  To solve this, the &amp;lt;tt&amp;gt;#format&amp;lt;/tt&amp;gt; property was introduced.  This pre-defines the order of format parameters.  Example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;quot;Phrases&amp;quot;&lt;br /&gt;
{&lt;br /&gt;
	//Example: &amp;quot;Bail's pants are on fire&amp;quot;&lt;br /&gt;
	&amp;quot;OnFire_plural&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s},{2:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;{1}'s {2} are on fire!&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;¡Los {2} de {1} están en llamas&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
	//Example: &amp;quot;Hello, Bail!&amp;quot;&lt;br /&gt;
	&amp;quot;Hello&amp;quot;&lt;br /&gt;
	{&lt;br /&gt;
		&amp;quot;#format&amp;quot;	&amp;quot;{1:s}&amp;quot;&lt;br /&gt;
		&amp;quot;en&amp;quot;		&amp;quot;Hello, {1}&amp;quot;&lt;br /&gt;
		&amp;quot;es&amp;quot;		&amp;quot;Hola, {1}&amp;quot;&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The format string is comprised of comma delimited sections, each section enclosed in brackets.  Each section has an ''index'' and a ''format specifier'', which are separated with a colon.  Format specifiers follow the general rules of [[Format Class Functions (SourceMod Scripting)|formatting]], however, only the following types are currently allowed:&lt;br /&gt;
*'''d'''/'''i''': Digits/Integer display&lt;br /&gt;
*'''x''': Hexadecimal display&lt;br /&gt;
*'''f''': Floating point display&lt;br /&gt;
*'''s''': String display&lt;br /&gt;
*'''c''': Character display (UTF-8 compatible)&lt;br /&gt;
&lt;br /&gt;
Note that currently, the special &amp;quot;%T&amp;quot; format type is not allowed inside a language translation string.  &lt;br /&gt;
&lt;br /&gt;
=Usage in a Plugin=&lt;br /&gt;
Plugins must call &amp;lt;tt&amp;gt;LoadTranslations&amp;lt;/tt&amp;gt; on each translation file they wish to use.  Failure to do so will cause any translations to fail, even if another plugin loads the same file.  This is to help prevent phrase-clashes between plugins.  &lt;br /&gt;
&lt;br /&gt;
'''Note''': Language files are reloaded every mapchange. Even if the plugin gets reloaded, the translation file stays cached until next map.&lt;br /&gt;
&lt;br /&gt;
Inline translation works in any [[Format Class Functions (SourceMod Scripting)|format-class]] of functions.  A new format specifier, '%T', is introduced, which instructs the format routine to insert a translated phrase.  Unlike all other format specifiers, this requires a minimum of two parameters:&lt;br /&gt;
*'''1st Parameter''': A string containing the phrase to be translated.&lt;br /&gt;
*'''2nd Parameter''': One of the following:&lt;br /&gt;
**The &amp;lt;tt&amp;gt;LANG_SERVER&amp;lt;/tt&amp;gt; constant, which specifies a translation to the default language.&lt;br /&gt;
**A player ID constant, which specifies a translation to the player's set language.&lt;br /&gt;
*'''3rd Parameter and higher''': Inputs into the phrase's format specifiers, if necessary.&lt;br /&gt;
&lt;br /&gt;
Examples of this are:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:name[32], String:buffer[128];&lt;br /&gt;
GetClientName(client, name, sizeof(name));&lt;br /&gt;
PrintToChat(client, &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, client, name);&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;[SourceMod] %T&amp;quot;, &amp;quot;Hello&amp;quot;, LANG_SERVER, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A breakdown of the format parameters:&lt;br /&gt;
*&amp;lt;tt&amp;gt;&amp;quot;Hello&amp;quot;&amp;lt;/tt&amp;gt;: The phrase to translate.&lt;br /&gt;
*&amp;lt;tt&amp;gt;client/LANG_SERVER&amp;lt;/tt&amp;gt;: Who to translate the phrase to.&lt;br /&gt;
*&amp;lt;tt&amp;gt;name&amp;lt;/tt&amp;gt;: The &amp;quot;Hello&amp;quot; phrase requires one string, so this will appear in the translated phrase.&lt;br /&gt;
&lt;br /&gt;
Lastly, there is a second form of inline translation, using '%t'.  This is only allowed in functions which act directly on one or more clients.  It eliminates the second parameter, and uses the original client specified.  Example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToChat(client, &amp;quot;[SourceMod] %t&amp;quot;, &amp;quot;Hello&amp;quot;, name);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you can see from this example, we did not have to specify the client index more than once.  Thus, it is usually more convenient to use the limited '%t' version in functions such as &amp;lt;tt&amp;gt;PrintToChat&amp;lt;/tt&amp;gt;.  However, in functions which are not &amp;quot;player directed,&amp;quot; such as &amp;lt;tt&amp;gt;Format&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;PrintToServer&amp;lt;/tt&amp;gt;, only '%T' can be used.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6751</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6751"/>
		<updated>2008-12-28T16:21:37Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Расширенный формат */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Формат классов функций, аргументов переменной - функции в [[SourceMod]] которые позволяют Вам форматировать строки. Простой пример этой &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; функции, выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если userName содержит &amp;quot;&amp;lt;tt&amp;gt;Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;, содержимое &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; будет: &amp;quot;&amp;lt;tt&amp;gt;Ваше имя: Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;. Прототип этих функций почти всегда содержит следующие параметры:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, обратите внимание на эти два выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; является формат-классовой функцией. Она может быть использована точно так же, как было показано ранее:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Спецификаторы Формата=&lt;br /&gt;
Спецификаторы Формата имеют код, который позволяет указать, какие типы данных будут отображаться. Наиболее распространенными спецификаторами являются:&lt;br /&gt;
*'''Числовые'''&lt;br /&gt;
**'''d''' или '''i''': Целое число как десятичные&lt;br /&gt;
**'''b''': Бинарные символы в значении&lt;br /&gt;
**'''f''': Числа с плавающей точкой&lt;br /&gt;
**'''x''' or '''X''': Шестнадцатеричное представление бинарных значений (применение заглавных букв влияет на шестнадцатеричный регистр букв)&lt;br /&gt;
*'''Символ(ы)'''&lt;br /&gt;
**'''s''': Строка&lt;br /&gt;
**'''t''' или '''T''': Переводы фраз (см. в [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Вывод одного символа (совместимо с UTF-8)&lt;br /&gt;
*'''Специальные'''&lt;br /&gt;
**'''L''': Требуется индекс клиента; расширяется до 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt;, где 1 - имя игрока, 2 - userid игрока, и 3 - Steam ID игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Требуется индекс клиента; расширяется до строки, содержащей имя игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Спецификаторы формата обозначаются символом &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt;. Например, чтобы отобразилось число с плавающей точкой, десятичное число и строка, Вы можете использовать этот код:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Десятичное число: %d Число с плавающей точкой: %f Строка: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Использование неправильных типов данных спецификаторов может быть очень опасно. Всегда убедитесь, что выводится правильный тип. Например, указание строки и передача числа, может привести к падению сервера.&lt;br /&gt;
&lt;br /&gt;
=Расширенный формат=&lt;br /&gt;
Спецификаторы формата имеют расширенный синтаксис для управления различными аспектами того, как будут выводиться данные.&lt;br /&gt;
Полный синтаксис: &amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый раздел в квадратных скобках является дополнительным расширением. Описание поддерживаемых SourceMod расширений формата:&lt;br /&gt;
*'''%''': Очевидно, что это требуется всегда.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Выравнивание по левому краю (выравнивание по правому краю установлено по умолчанию)&lt;br /&gt;
**'''0''': Заполняет 0 вместо пробелов в случае необходимости (см. '''width''' ниже).&lt;br /&gt;
*'''width''': Минимальное количество символов, которые будут отображены. Если отображаемая величина будет короче, чем это число, результат будет заполнен пустым пространством. Значение так же не обрежится, даже если результат будет длинее.&lt;br /&gt;
*'''precision''':&lt;br /&gt;
**'''For integers''': определяет минимальное количество цифр для отображения (или заполняет пробелами/нулями, если она меньше минимальной).&lt;br /&gt;
**'''For strings''': определяет максимальное количество символов для отображения.&lt;br /&gt;
**'''For floats''': определяет количество цифр для отображения ''после запятой''.&lt;br /&gt;
**'''For all other types''': нет эффекта.&lt;br /&gt;
*'''specifier''': символ указывающий тип данных (требуется всегда).&lt;br /&gt;
&lt;br /&gt;
Для получения более подробной информации см. [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] из C Standard Library, хотя не Все режимы из C поддерживаются.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6750</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6750"/>
		<updated>2008-12-28T16:19:50Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Расширенное форматирование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Формат классов функций, аргументов переменной - функции в [[SourceMod]] которые позволяют Вам форматировать строки. Простой пример этой &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; функции, выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если userName содержит &amp;quot;&amp;lt;tt&amp;gt;Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;, содержимое &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; будет: &amp;quot;&amp;lt;tt&amp;gt;Ваше имя: Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;. Прототип этих функций почти всегда содержит следующие параметры:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, обратите внимание на эти два выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; является формат-классовой функцией. Она может быть использована точно так же, как было показано ранее:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Спецификаторы Формата=&lt;br /&gt;
Спецификаторы Формата имеют код, который позволяет указать, какие типы данных будут отображаться. Наиболее распространенными спецификаторами являются:&lt;br /&gt;
*'''Числовые'''&lt;br /&gt;
**'''d''' или '''i''': Целое число как десятичные&lt;br /&gt;
**'''b''': Бинарные символы в значении&lt;br /&gt;
**'''f''': Числа с плавающей точкой&lt;br /&gt;
**'''x''' or '''X''': Шестнадцатеричное представление бинарных значений (применение заглавных букв влияет на шестнадцатеричный регистр букв)&lt;br /&gt;
*'''Символ(ы)'''&lt;br /&gt;
**'''s''': Строка&lt;br /&gt;
**'''t''' или '''T''': Переводы фраз (см. в [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Вывод одного символа (совместимо с UTF-8)&lt;br /&gt;
*'''Специальные'''&lt;br /&gt;
**'''L''': Требуется индекс клиента; расширяется до 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt;, где 1 - имя игрока, 2 - userid игрока, и 3 - Steam ID игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Требуется индекс клиента; расширяется до строки, содержащей имя игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Спецификаторы формата обозначаются символом &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt;. Например, чтобы отобразилось число с плавающей точкой, десятичное число и строка, Вы можете использовать этот код:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Десятичное число: %d Число с плавающей точкой: %f Строка: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Использование неправильных типов данных спецификаторов может быть очень опасно. Всегда убедитесь, что выводится правильный тип. Например, указание строки и передача числа, может привести к падению сервера.&lt;br /&gt;
&lt;br /&gt;
=Расширенный формат=&lt;br /&gt;
Спецификаторы формата имеют расширенный синтаксис для управления различными аспектами того, как будут выводиться данные. Полный синтаксис: &amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый раздел в квадратных скобках является дополнительным расширением. Описание поддерживаемых SourceMod расширений формата:&lt;br /&gt;
*'''%''': Очевидно, что это требуется всегда.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Выравнивание по левому краю (выравнивание по правому краю установлено по умолчанию)&lt;br /&gt;
**'''0''': Заполняет 0 вместо пробелов в случае необходимости (см. '''width''' ниже).&lt;br /&gt;
*'''width''': Минимальное количество символов, которые будут отображены. Если отображаемая величина будет короче, чем это число, результат будет заполнен пустым пространством. Значение так же не обрежится, даже если результат будет длинее.&lt;br /&gt;
*'''precision''':&lt;br /&gt;
**'''For integers''': определяет минимальное количество цифр для отображения (или заполняет пробелами/нулями, если она меньше минимальной).&lt;br /&gt;
**'''For strings''': определяет максимальное количество символов для отображения.&lt;br /&gt;
**'''For floats''': определяет количество цифр для отображения ''после запятой''.&lt;br /&gt;
**'''For all other types''': нет эффекта.&lt;br /&gt;
*'''specifier''': символ указывающий тип данных (требуется всегда).&lt;br /&gt;
&lt;br /&gt;
Для получения более подробной информации см. [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] из C Standard Library, хотя не Все режимы поддерживаются из C.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6749</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6749"/>
		<updated>2008-12-28T15:28:55Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Испрльзование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Формат классов функций, аргументов переменной - функции в [[SourceMod]] которые позволяют Вам форматировать строки. Простой пример этой &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; функции, выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если userName содержит &amp;quot;&amp;lt;tt&amp;gt;Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;, содержимое &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; будет: &amp;quot;&amp;lt;tt&amp;gt;Ваше имя: Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;. Прототип этих функций почти всегда содержит следующие параметры:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, обратите внимание на эти два выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; является формат-классовой функцией. Она может быть использована точно так же, как было показано ранее:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Спецификаторы Формата=&lt;br /&gt;
Спецификаторы Формата имеют код, который позволяет указать, какие типы данных будут отображаться. Наиболее распространенными спецификаторами являются:&lt;br /&gt;
*'''Числовые'''&lt;br /&gt;
**'''d''' или '''i''': Целое число как десятичные&lt;br /&gt;
**'''b''': Бинарные символы в значении&lt;br /&gt;
**'''f''': Числа с плавающей точкой&lt;br /&gt;
**'''x''' or '''X''': Шестнадцатеричное представление бинарных значений (применение заглавных букв влияет на шестнадцатеричный регистр букв)&lt;br /&gt;
*'''Символ(ы)'''&lt;br /&gt;
**'''s''': Строка&lt;br /&gt;
**'''t''' или '''T''': Переводы фраз (см. в [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Вывод одного символа (совместимо с UTF-8)&lt;br /&gt;
*'''Специальные'''&lt;br /&gt;
**'''L''': Требуется индекс клиента; расширяется до 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt;, где 1 - имя игрока, 2 - userid игрока, и 3 - Steam ID игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Требуется индекс клиента; расширяется до строки, содержащей имя игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Спецификаторы формата обозначаются символом &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt;. Например, чтобы отобразилось число с плавающей точкой, десятичное число и строка, Вы можете использовать этот код:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Десятичное число: %d Число с плавающей точкой: %f Строка: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Примечание''': Использование неправильных типов данных спецификаторов может быть очень опасно. Всегда убедитесь, что выводится правильный тип. Например, указание строки и передача числа, может привести к падению сервера.&lt;br /&gt;
&lt;br /&gt;
=Расширенное форматирование=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6748</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6748"/>
		<updated>2008-12-28T14:21:39Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Format Specifiers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Формат классов функций, аргументов переменной - функции в [[SourceMod]] которые позволяют Вам форматировать строки. Простой пример этой &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; функции, выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если userName содержит &amp;quot;&amp;lt;tt&amp;gt;Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;, содержимое &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; будет: &amp;quot;&amp;lt;tt&amp;gt;Ваше имя: Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;. Прототип этих функций почти всегда содержит следующие параметры:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, обратите внимание на эти два выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; является формат-классовой функцией. Она может быть использована точно так же, как было показано ранее:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Спецификаторы Формата=&lt;br /&gt;
Спецификаторы Формата имеют код, который позволяет указать, какие типы данных будут отображаться. Наиболее распространенными спецификаторами являются:&lt;br /&gt;
*'''Числовые'''&lt;br /&gt;
**'''d''' или '''i''': Целое число как десятичные&lt;br /&gt;
**'''b''': Бинарные символы в значении&lt;br /&gt;
**'''f''': Числа с плавающей точкой&lt;br /&gt;
**'''x''' or '''X''': Шестнадцатеричное представление бинарных значений (применение заглавных букв влияет на шестнадцатеричный регистр букв)&lt;br /&gt;
*'''Символ(ы)'''&lt;br /&gt;
**'''s''': Строка&lt;br /&gt;
**'''t''' или '''T''': Переводы фраз (см. в [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Вывод одного символа (совместимо с UTF-8)&lt;br /&gt;
*'''Специальные'''&lt;br /&gt;
**'''L''': Требуется индекс клиента; расширяется до 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt;, где 1 - имя игрока, 2 - userid игрока, и 3 - Steam ID игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Требуется индекс клиента; расширяется до строки, содержащей имя игрока. Если клиент имеет индекс 0, строка будет: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Расширенное форматирование=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6747</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6747"/>
		<updated>2008-12-27T17:44:53Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Введение */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Формат классов функций, аргументов переменной - функции в [[SourceMod]] которые позволяют Вам форматировать строки. Простой пример этой &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; функции, выглядит следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если userName содержит &amp;quot;&amp;lt;tt&amp;gt;Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;, содержимое &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; будет: &amp;quot;&amp;lt;tt&amp;gt;Ваше имя: Frenzzy&amp;lt;/tt&amp;gt;&amp;quot;. Прототип этих функций почти всегда содержит следующие параметры:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Например, обратите внимание на эти два выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Таким образом, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; является формат-классовой функцией. Она может быть использована точно так же, как было показано ранее:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Ваше имя: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Format Specifiers=&lt;br /&gt;
A format specifier is a code that allows you to specify what data-type to print.  The most common specifiers are:&lt;br /&gt;
*'''Numerical'''&lt;br /&gt;
**'''d''' or '''i''': Integer number as decimal&lt;br /&gt;
**'''b''': Binary digits in the value&lt;br /&gt;
**'''f''': Floating-point number&lt;br /&gt;
**'''x''' or '''X''': Hexadecimal representation of the binary value (capitalization affects hex letter casing)&lt;br /&gt;
*'''Character(s)'''&lt;br /&gt;
**'''s''': String&lt;br /&gt;
**'''t''' or '''T''': Translates a phrase (explained in [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Prints one character (UTF-8 compliant)&lt;br /&gt;
*'''Special'''&lt;br /&gt;
**'''L''': Requires a client index; expands to 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt; where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Requires a client index; expands to a string containing the player's name.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Расширенное форматирование=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6746</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6746"/>
		<updated>2008-12-27T17:23:29Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Продвинутое форматирование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; function, which looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If userName contains &amp;quot;&amp;lt;tt&amp;gt;Mark&amp;lt;/tt&amp;gt;,&amp;quot; the contents of &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; will then be: &amp;quot;&amp;lt;tt&amp;gt;Your name is: Mark&amp;lt;/tt&amp;gt;.&amp;quot;  The prototype of these functions almost always contains the following parameters:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, observe the following two natives:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; is a format-class function.  It can be used exactly as shown earlier:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Format Specifiers=&lt;br /&gt;
A format specifier is a code that allows you to specify what data-type to print.  The most common specifiers are:&lt;br /&gt;
*'''Numerical'''&lt;br /&gt;
**'''d''' or '''i''': Integer number as decimal&lt;br /&gt;
**'''b''': Binary digits in the value&lt;br /&gt;
**'''f''': Floating-point number&lt;br /&gt;
**'''x''' or '''X''': Hexadecimal representation of the binary value (capitalization affects hex letter casing)&lt;br /&gt;
*'''Character(s)'''&lt;br /&gt;
**'''s''': String&lt;br /&gt;
**'''t''' or '''T''': Translates a phrase (explained in [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Prints one character (UTF-8 compliant)&lt;br /&gt;
*'''Special'''&lt;br /&gt;
**'''L''': Requires a client index; expands to 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt; where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Requires a client index; expands to a string containing the player's name.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Расширенное форматирование=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6745</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6745"/>
		<updated>2008-12-27T17:21:01Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Введение=&lt;br /&gt;
Format-class functions are variable argument functions in [[SourceMod]] which allow you to format a string.  A simple example of this is the &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt; function, which looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:buffer[512];&lt;br /&gt;
Format(buffer, sizeof(buffer), &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If userName contains &amp;quot;&amp;lt;tt&amp;gt;Mark&amp;lt;/tt&amp;gt;,&amp;quot; the contents of &amp;lt;tt&amp;gt;buffer&amp;lt;/tt&amp;gt; will then be: &amp;quot;&amp;lt;tt&amp;gt;Your name is: Mark&amp;lt;/tt&amp;gt;.&amp;quot;  The prototype of these functions almost always contains the following parameters:&lt;br /&gt;
&amp;lt;pawn&amp;gt;const String:fmt[], {Handle,Float,_}:...&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, observe the following two natives:&lt;br /&gt;
&amp;lt;pawn&amp;gt;native Format(String:buffer[], maxlength, const String:fmt[], {Handle,Float,_}:...);&lt;br /&gt;
native PrintToClient(client, String:fmt[], {Handle,Float,_}:...);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Thus, &amp;lt;tt&amp;gt;PrintToClient&amp;lt;/tt&amp;gt; is a format-class function.  It can be used exactly as shown earlier:&lt;br /&gt;
&amp;lt;pawn&amp;gt;PrintToClient(client, &amp;quot;Your name is: %s&amp;quot;, userName);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Format Specifiers=&lt;br /&gt;
A format specifier is a code that allows you to specify what data-type to print.  The most common specifiers are:&lt;br /&gt;
*'''Numerical'''&lt;br /&gt;
**'''d''' or '''i''': Integer number as decimal&lt;br /&gt;
**'''b''': Binary digits in the value&lt;br /&gt;
**'''f''': Floating-point number&lt;br /&gt;
**'''x''' or '''X''': Hexadecimal representation of the binary value (capitalization affects hex letter casing)&lt;br /&gt;
*'''Character(s)'''&lt;br /&gt;
**'''s''': String&lt;br /&gt;
**'''t''' or '''T''': Translates a phrase (explained in [[Translations (SourceMod_Scripting)#Inline_Translations|Inline Translations]])&lt;br /&gt;
**'''c''': Prints one character (UTF-8 compliant)&lt;br /&gt;
*'''Special'''&lt;br /&gt;
**'''L''': Requires a client index; expands to 1&amp;lt;2&amp;gt;&amp;lt;3&amp;gt;&amp;lt;&amp;gt; where 1 is the player's name, 2 is the player's userid, and 3 is the player's Steam ID.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;Console&amp;lt;0&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;Console&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;&lt;br /&gt;
**'''N''': Requires a client index; expands to a string containing the player's name.  If the client index is 0, the string will be: &amp;lt;tt&amp;gt;Console&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Испрльзование=&lt;br /&gt;
Format specifiers are denoted with a &amp;lt;tt&amp;gt;'%s'&amp;lt;/tt&amp;gt; symbol.  For example, to print a float, a number, and a string, you might use this code:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Float:fNum = 5.0;&lt;br /&gt;
new iNum = 5&lt;br /&gt;
new String:str[] = &amp;quot;5&amp;quot;&lt;br /&gt;
&lt;br /&gt;
PrintToClient(client, &amp;quot;Number: %d Float: %f String: %s&amp;quot;, iNum, fNum, str);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Note''': Using the wrong data type with a specifier can be very dangerous.  Always make sure you are printing as the right type.  For example, specifying a string and passing a number can crash the server.&lt;br /&gt;
&lt;br /&gt;
=Продвинутое форматирование=&lt;br /&gt;
Format specifiers have an extended syntax for controlling various aspects of how data is printed.  The full syntax is:&lt;br /&gt;
&amp;lt;tt&amp;gt;%[flags][width][.precision]specifier&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each bracketed section is an optional extension.  Explanations of supported SourceMod format extensions:&lt;br /&gt;
*'''%''': Obviously, this is always required.&lt;br /&gt;
*'''flags''':&lt;br /&gt;
**'''-''': Left-justify (right-justify is set by default)&lt;br /&gt;
**'''0''': Pads with 0s instead of spaces when needed (see '''width''' below).&lt;br /&gt;
*'''width''': Minimum number of characters to be printed. If the value to be printed is shorter than this number, the result is padded with blank spaces. The value is not truncated even if the result is larger.&lt;br /&gt;
*'''precision''': &lt;br /&gt;
**'''For integers''': specifies the minimum number of digits to print (or pad with spaces/zeroes if below the minimum).  &lt;br /&gt;
**'''For strings''': specifies the maximum number of characters to print.&lt;br /&gt;
**'''For floats''': specifies the number of digits to be printed ''after the decimal point''.&lt;br /&gt;
**'''For all other types''': no effect.&lt;br /&gt;
*'''specifier''': character specifying the data type (always required).&lt;br /&gt;
&lt;br /&gt;
For more information, see [http://www.cplusplus.com/reference/clibrary/cstdio/printf.html printf] from the C Standard Library, although not all modes are supported from C.&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6744</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6744"/>
		<updated>2008-12-27T17:19:59Z</updated>

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

		<summary type="html">&lt;p&gt;Frenzzy: /* Информация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта категория содержит статьи о написании скриптов под SourceMod с использованием SourcePawn.&lt;br /&gt;
&lt;br /&gt;
===Введение===&lt;br /&gt;
*[[Ru:Introduction to SourcePawn|Ru:Introduction to SourcePawn]] - Введение в SourcePawn. Обучение синтаксису языка.&lt;br /&gt;
*[[Ru:Introduction to SourceMod Plugins|Ru:Introduction to SourceMod Plugins]] - Введение в SourceMod плагины. Создаем Ваш &amp;quot;первый плагин&amp;quot;.&lt;br /&gt;
*[http://docs.sourcemod.net/api API Reference] - Поиск сценариев в справочнике API.&lt;br /&gt;
&lt;br /&gt;
===Основной API===&lt;br /&gt;
*[[Ru:AutoConfigs (SourceMod Scripting)|Ru:AutoConfigs]] - Автоматическое создание .cfg файлов.&lt;br /&gt;
*[[Ru:Commands (SourceMod Scripting)|Ru:Commands]] - Консольные команды/ввод.&lt;br /&gt;
*[[Ru:ConVars (SourceMod Scripting)|Ru:ConVars]] - Консольные переменные (cvars).&lt;br /&gt;
*[[Ru:Events (SourceMod Scripting)|Ru:Events]] - Игровые события Half-Life.&lt;br /&gt;
*[[Ru:KeyValues (SourceMod Scripting)|Ru:KeyValues]] - KeyValues анализ/запись файла.&lt;br /&gt;
*[[Ru:Menu API (SourceMod)|Ru:Menus]] - Создание и отображение меню.&lt;br /&gt;
*[[Ru:SQL (SourceMod Scripting)|Ru:SQL]] - Использование баз данных (MySQL, SQLite).&lt;br /&gt;
*[[Ru:Timers (SourceMod Scripting)|Ru:Timers]] - Вызов таймеров.&lt;br /&gt;
*[[Ru:Translations (SourceMod Scripting)|Ru:Translations]] - Создание локализаций.&lt;br /&gt;
&lt;br /&gt;
===Продвинутый API===&lt;br /&gt;
*[[Admin API (SourceMod)|Administration API]] - Использование кэша администратора.&lt;br /&gt;
*[[Admin Menu (SourceMod Scripting)|Admin Menu API]] - Закрепление в меню администратора.&lt;br /&gt;
*[[Creating Natives (SourceMod Scripting)|Creating Natives]] - Разоблачение API других плагинов.&lt;br /&gt;
*[[Function Calling API (SourceMod Scripting)|Function Calling API]] - Вызовы внешних функций.&lt;br /&gt;
*[[Optional Requirements (SourceMod Scripting)|Optional Requirements]] - Управление зависимостями.&lt;br /&gt;
*[[SDKTools (SourceMod Scripting)|SDKTools]] - Использование мощного SDK уровней абстракции.&lt;br /&gt;
*[[TempEnts (SourceMod SDKTools)|Temporary Entities]] - Использование временных объектов.&lt;br /&gt;
&lt;br /&gt;
===Информация===&lt;br /&gt;
*[[Deprecation Schedule (SourceMod Scripting)|Deprecation Schedule]] - Which functions are getting removed.&lt;br /&gt;
*[[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]] - All about text formatting.&lt;br /&gt;
*[[Handles (SourceMod Scripting)|Handles]] - Overview of Handles and some common types.&lt;br /&gt;
*[[Optimizing Plugins (SourceMod Scripting)|Optimizing Plugins]] - Optimization hints.&lt;br /&gt;
*[[Tags (Scripting)|Tags]] - All about tags.&lt;br /&gt;
*[[Vectors Explained (Scripting)|Vectors Explained]] - Explanation of Vector types.&lt;br /&gt;
&lt;br /&gt;
===Дополнительные средства===&lt;br /&gt;
*[http://docs.sourcemod.net/api API Reference] - Searchable scripting API reference.&lt;br /&gt;
*[[Entity Properties]] - Explanation of Source entity properties.&lt;br /&gt;
*[[Game Events (Source)|Game Events]] - Game events listings for popular mods.&lt;br /&gt;
*[[Mod TempEnt List (Source)|Temp Entity Lists]] - Temporary entities for popular mods.&lt;br /&gt;
*[[SourceMod Profiler]] - Performance tracking and optimizing.&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6742</id>
		<title>Ru:Format Class Functions (SourceMod Scripting)</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Format_Class_Functions_(SourceMod_Scripting)&amp;diff=6742"/>
		<updated>2008-12-27T17:18:28Z</updated>

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

		<summary type="html">&lt;p&gt;Frenzzy: /* Отображение активности, логирование */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Отображение активности, логирование=&lt;br /&gt;
Почти все команды администратора должны логировать (записывать в лог) их активность, а некоторые команды администратора должны отобразить свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6740</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6740"/>
		<updated>2008-12-27T17:10:52Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Отображение активности, логирование=&lt;br /&gt;
Почти все команды администратора должны логировать (записывать в лог) их активность, а некоторые команды администратора должны отобразить свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6739</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6739"/>
		<updated>2008-12-27T17:09:23Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Showing Activity, Logging */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
=Отображение активности, запись=&lt;br /&gt;
Почти все команды администратора должны записывать их активность, а некоторые команды администратора должны показать свою активность в игре для клиентов. Это может быть сделано через [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] и [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] функции. Точное функциональность ShowActivity2() определяется &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; переменной.&lt;br /&gt;
&lt;br /&gt;
Например, давайте перепишем несколько последних строк нашей slap команды:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6738</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6738"/>
		<updated>2008-12-27T17:04:07Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* ConVars */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается без изменений! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6737</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6737"/>
		<updated>2008-12-27T17:02:02Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* ConVars */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, известные также как cvars, глобальные консольные переменные в движке Source. Они могут иметь целые, десятичные, или строковые значения. Доступ к ConVar осуществляется через дескрипторы ([[Handles (SourceMod Scripting)|Handles]]). С тех пор как ConVars имеют глобальный характер, Вам не нужно закрывать дескрипторы ConVar (фактически, Вы и не можете).&lt;br /&gt;
&lt;br /&gt;
Удобная особенность ConVars заключается в том, что они легко настраиваются пользователями. Они могут быть помещены в любой .cfg файл, например &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;. Чтобы сделать удобнее их использование, SourceMod имеет [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] функции. Эта функция автоматически создает .cfg файл по умолчанию, содержащий все Ваши переменные (cvars), снабженные комментариями для пользователей. Очень рекомендую Вам вызывать её, если у Вас есть настраиваемые ConVars.&lt;br /&gt;
&lt;br /&gt;
Давайте усовершенствуем Наш предыдущий пример новой ConVar. ConVar назовём &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; и она будет определять повреждение по умолчанию для удара игрока, если размер повреждений не указан.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Остальное остается не тронутым! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6733</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6733"/>
		<updated>2008-12-26T14:51:26Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Реализация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Попытка и нахождение соответствия игрока */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6732</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6732"/>
		<updated>2008-12-26T14:44:05Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Реализация==&lt;br /&gt;
Давайте решим, что команда будет выглядеть так. Пусть будет она действовать как команда по умолчанию &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы осуществить это, Нам потребуется несколько шагов:&lt;br /&gt;
*Получить ввод с консоли. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Найти соответствия игрока. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Ударить его. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], которая требует в том числе &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt; расширение в комплекте с SourceMod.&lt;br /&gt;
*Сообщить администратору. Для этого мы используем [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Полный пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Получаем первый аргумент */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* Если есть 2 или более аргументов, и второй аргумент получен&lt;br /&gt;
	 * успешно, превратить его в целое.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() автоматически отвечает с&lt;br /&gt;
		 * причиной провала.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] Вас ударил %s на %d повреждений!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для получения дополнительной информации о том, что такое %s и %d, см. [[Ru:Format Class Functions (SourceMod Scripting)|Ru:Format Class Functions]]. Имейте в виду, что Вам никогда не придется отменять или удалить Ваши команды администратора. Если плагин выгружается, SourceMod очищает их за Вас.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6731</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6731"/>
		<updated>2008-12-26T14:25:13Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Declaration */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Во-первых, давайте смотреть на то, какая команда требуется администратору. Команды администратора регистрируются с использованием функции [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd]. Она требует '''название''', '''функцию обратного вызова''' и '''флаги админа по умолчанию'''.&lt;br /&gt;
&lt;br /&gt;
Функция обратного вызова это то, на что ссылаться используемая команда каждый раз. [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Нажми здесь], чтобы просмотреть её прототип. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь Мы успешно обеспечили выполнение команды -- хотя она не будет ничего делать. На самом деле, она скажет &amp;quot;Неизвестная команда&amp;quot;, если Вы используете её! Причина в том, что отсутствует &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; тег. По умолчанию функция ввода консольных команд заключается в том, чтобы ответить о неизвестной команде. Чтобы заблокировать эту функцию, вы должны создать новое действие:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Теперь команда не будет сообщать об ошибке, но она по-прежнему не будет ничего делать.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6730</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6730"/>
		<updated>2008-12-26T14:07:46Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Commands */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Команды=&lt;br /&gt;
В Нашем первом примере будет написана простая команда для администратора, чтобы ударить игрока. Мы будем расширять функциональность этого примера, пока не получим окончательный результат, максимально полным.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  The default functionality for entering console commands is to reply that they are unknown.  To block this functionality, you must return a new action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6729</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6729"/>
		<updated>2008-12-26T14:00:40Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Includes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Включения=&lt;br /&gt;
Pawn требует включать файлы '''include''', как и C требует наличие заголовка у файла. Включение списков файлов всех структур, функций, вызовы и тегов, которые имеются в наличии. Есть три типа файлов:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;, и все его включения. Все представленные в SourceMod Core.&lt;br /&gt;
*'''Extension''' - добавляет зависимость от определенного расширения.&lt;br /&gt;
*'''Plugin''' - добавляет зависимость от некоторых плагинов.&lt;br /&gt;
&lt;br /&gt;
Файлы включения загружаются с помощью &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; указателя компилятора.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  The default functionality for entering console commands is to reply that they are unknown.  To block this functionality, you must return a new action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6728</id>
		<title>Ru:Introduction to SourceMod Plugins</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourceMod_Plugins&amp;diff=6728"/>
		<updated>2008-12-26T13:53:12Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Plugin Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство даст Вам основные понятия о написании [[SourceMod]] плагинов. Если вы не знакомы с языком SourcePawn, то Мы настоятельно рекомендуем ознакомиться со статьей [[Ru:Introduction to SourcePawn]] (Введение в SourcePawn).&lt;br /&gt;
&lt;br /&gt;
Для получения информации о компиляции плагинов см. [[Compiling SourceMod Plugins]] (Компиляция SourceMod плагинов). Автор настоящей статьи использует редактор [http://www.crimsoneditor.com/ Crimson Editor] для написания плагинов. Вы можете использовать [http://www.pspad.com/ PSPad], [http://www.ultraedit.com/ UltraEdit], [http://notepad-plus.sourceforge.net/uk/site.htm Notepad++], [http://www.textpad.com/ TextPad], [http://sourceforge.net/projects/pawnstudio/ SourceMod IDE] или любой другой текстовый редактор.&lt;br /&gt;
&lt;br /&gt;
=Структура плагина=&lt;br /&gt;
Почти все плагины имеют три одинаковых элемента:&lt;br /&gt;
*'''Includes''' - Позволяет получить доступ к SourceMod API, и если Вы хотите, к API от внешних SourceMod плагинов и расширений.&lt;br /&gt;
*'''Info''' - Общественная информация о Вашем плагине.&lt;br /&gt;
*'''Startup''' - Функция, которая осуществляет запуск процедур в Вашем плагине.&lt;br /&gt;
&lt;br /&gt;
Плагин скелетной структуры выглядит следующим образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;Мой первый плагин&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Я&amp;quot;,&lt;br /&gt;
	description = &amp;quot;Мой первый супер плагин&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	// Выполнение единовременного запуска задач ...&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Информация часть имеет специальную синтаксическую конструкцию. Вы не можете изменить любое из ключевых слов, или объявление &amp;lt;tt&amp;gt;public Plugin:myinfo&amp;lt;/tt&amp;gt;. Хорошая идея заключается в том, чтобы скопировать и вставить эту скелетную структуру и отредактировать строки, чтобы начать работу.&lt;br /&gt;
&lt;br /&gt;
=Includes=&lt;br /&gt;
Pawn requires '''include files''', much like C requires header files.  Include files list all of the structures, functions, callbacks, and tags that are available.  There are three types of include files:&lt;br /&gt;
*'''Core''' - &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt; and anything it includes.  These are all provided by SourceMod's Core.&lt;br /&gt;
*'''Extension''' - adds a dependency against a certain extension.&lt;br /&gt;
*'''Plugin''' - adds a dependency against a certain plugin.&lt;br /&gt;
&lt;br /&gt;
Include files are loaded using the &amp;lt;tt&amp;gt;#include&amp;lt;/tt&amp;gt; compiler directive.&lt;br /&gt;
&lt;br /&gt;
=Commands=&lt;br /&gt;
Our first example will be writing a simple admin command to slap a player.  We'll continue to extend this example with more features until we have a final, complete result.&lt;br /&gt;
&lt;br /&gt;
==Declaration==&lt;br /&gt;
First, let's look at what an admin command requires.  Admin commands are registered using the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=471&amp;amp; RegAdminCmd] function.  They require a '''name''', a '''callback function''', and '''default admin flags'''.  &lt;br /&gt;
&lt;br /&gt;
The callback function is what's invoked every time the command is used.  [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=469&amp;amp; Click here] to see its prototype.  Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now we've successfully implemented a command -- though it doesn't do anything yet.  In fact, it will say &amp;quot;Unknown command&amp;quot; if you use it!  The reason is because of the &amp;lt;tt&amp;gt;Action&amp;lt;/tt&amp;gt; tag.  The default functionality for entering console commands is to reply that they are unknown.  To block this functionality, you must return a new action:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now the command will report no error, but it still won't do anything.&lt;br /&gt;
&lt;br /&gt;
==Implementation==&lt;br /&gt;
Let's decide what the command will look like.  Let's have it act like the default &amp;lt;tt&amp;gt;sm_slap&amp;lt;/tt&amp;gt; command:&lt;br /&gt;
&amp;lt;pre&amp;gt;sm_myslap &amp;lt;name|#userid&amp;gt; [damage]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To implement this, we'll need a few steps:&lt;br /&gt;
*Get the input from the console.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=473&amp;amp; GetCmdArg()].&lt;br /&gt;
*Find a matching player.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=144&amp;amp; FindTarget()].&lt;br /&gt;
*Slap them.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=42&amp;amp; SlapPlayer()], which requires including &amp;lt;tt&amp;gt;sdktools&amp;lt;/tt&amp;gt;, an extension bundled with SourceMod.&lt;br /&gt;
*Respond to the admin.  For this we use [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=462&amp;amp; ReplyToCommand()].&lt;br /&gt;
&lt;br /&gt;
Full example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/* Try and find a matching player */&lt;br /&gt;
	new target = FindTarget(client, arg1)&lt;br /&gt;
	if (target == -1)&lt;br /&gt;
	{&lt;br /&gt;
		/* FindTarget() automatically replies with the &lt;br /&gt;
		 * failure reason.&lt;br /&gt;
		 */&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
	ReplyToCommand(client, &amp;quot;[SM] You slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
&lt;br /&gt;
	return Plugin_Handled;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For more information on what %s and %d are, see [[Format Class Functions (SourceMod Scripting)|Format Class Functions]].  Note that you never need to unregister or remove your admin command.  When a plugin is unloaded, SourceMod cleans it up for you.&lt;br /&gt;
&lt;br /&gt;
=ConVars=&lt;br /&gt;
ConVars, also known as cvars, are global console variables in the Source engine.  They can have integer, float, or string values.  ConVar accessing is done through [[Handles (SourceMod Scripting)|Handles]].  Since ConVars are global, you do not need to close ConVar Handles (in fact, you cannot).&lt;br /&gt;
&lt;br /&gt;
The handy feature of ConVars is that they are easy for users to configure.  They can be placed in any .cfg file, such as &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;.  To make this easier, SourceMod has an [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=607&amp;amp; AutoExecConfig()] function.  This function will automatically build a default .cfg file containing all of your cvars, annotated with comments, for users.  It is highly recommend that you call this if you have customizable ConVars.&lt;br /&gt;
&lt;br /&gt;
Let's extend your example from earlier with a new ConVar.  Our ConVar will be &amp;lt;tt&amp;gt;sm_myslap_damage&amp;lt;/tt&amp;gt; and will specify the default damage someone is slapped for if no damage is specified.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* The rest remains unchanged! */&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Showing Activity, Logging=&lt;br /&gt;
Almost all admin commands should log their activity, and some admin commands should show their activity to in-game clients.  This can be done via the [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=599&amp;amp; LogAction()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=466&amp;amp; ShowActivity2()] functions.  The exact functionality of ShowActivity2() is determined by the &amp;lt;tt&amp;gt;sm_show_activity&amp;lt;/tt&amp;gt; cvar.&lt;br /&gt;
&lt;br /&gt;
For example, let's rewrite the last few lines of our slap command:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
	SlapPlayer(target, damage)&lt;br /&gt;
&lt;br /&gt;
	new String:name[MAX_NAME_LENGTH]&lt;br /&gt;
	&lt;br /&gt;
	GetClientName(target, name, sizeof(name))&lt;br /&gt;
&lt;br /&gt;
	ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, name, damage)&lt;br /&gt;
	LogAction(client, target, &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target, damage)&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;
=Multiple Targets=&lt;br /&gt;
To fully complete our slap demonstration, let's make it support multiple targets.  SourceMod's [[Admin_Commands_%28SourceMod%29#How_to_Target|targeting system]] is quite advanced, so using it may seem complicated at first.  &lt;br /&gt;
&lt;br /&gt;
The function we use is [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=703&amp;amp; ProcessTargetString()].  It takes in input from the console, and returns a list of matching clients.  It also returns a noun that will identify either a single client or describe a list of clients.  The idea is that each client is then processed, but the activity shown to all players is only processed once.  This reduces screen spam.&lt;br /&gt;
&lt;br /&gt;
This method of target processing is used for almost every admin command in SourceMod, and in fact FindTarget() is just a simplified version.&lt;br /&gt;
&lt;br /&gt;
Full, final example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
#include &amp;lt;sourcemod&amp;gt;&lt;br /&gt;
#include &amp;lt;sdktools&amp;gt;&lt;br /&gt;
&lt;br /&gt;
new Handle:sm_myslap_damage = INVALID_HANDLE&lt;br /&gt;
&lt;br /&gt;
public Plugin:myinfo =&lt;br /&gt;
{&lt;br /&gt;
	name = &amp;quot;My First Plugin&amp;quot;,&lt;br /&gt;
	author = &amp;quot;Me&amp;quot;,&lt;br /&gt;
	description = &amp;quot;My first plugin ever&amp;quot;,&lt;br /&gt;
	version = &amp;quot;1.0.0.0&amp;quot;,&lt;br /&gt;
	url = &amp;quot;http://www.sourcemod.net/&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
	LoadTranslations(&amp;quot;common.phrases&amp;quot;)&lt;br /&gt;
	RegAdminCmd(&amp;quot;sm_myslap&amp;quot;, Command_MySlap, ADMFLAG_SLAY)&lt;br /&gt;
&lt;br /&gt;
	sm_myslap_damage = CreateConVar(&amp;quot;sm_myslap_damage&amp;quot;, &amp;quot;5&amp;quot;, &amp;quot;Default slap damage&amp;quot;)&lt;br /&gt;
	AutoExecConfig(true, &amp;quot;plugin_myslap&amp;quot;)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Action:Command_MySlap(client, args)&lt;br /&gt;
{&lt;br /&gt;
	new String:arg1[32], String:arg2[32]&lt;br /&gt;
	new damage = GetConVarInt(sm_myslap_damage)&lt;br /&gt;
&lt;br /&gt;
	/* Get the first argument */&lt;br /&gt;
	GetCmdArg(1, arg1, sizeof(arg1))&lt;br /&gt;
&lt;br /&gt;
	/* If there are 2 or more arguments, and the second argument fetch &lt;br /&gt;
	 * is successful, convert it to an integer.&lt;br /&gt;
	 */&lt;br /&gt;
	if (args &amp;gt;= 2 &amp;amp;&amp;amp; GetCmdArg(2, arg2, sizeof(arg2)))&lt;br /&gt;
	{&lt;br /&gt;
		damage = StringToInt(arg2)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	/**&lt;br /&gt;
	 * target_name - stores the noun identifying the target(s)&lt;br /&gt;
	 * target_list - array to store clients&lt;br /&gt;
	 * target_count - variable to store number of clients&lt;br /&gt;
	 * tn_is_ml - stores whether the noun must be translated&lt;br /&gt;
	 */&lt;br /&gt;
	new String:target_name[MAX_TARGET_LENGTH]&lt;br /&gt;
	new target_list[MAXPLAYERS], target_count&lt;br /&gt;
	new bool:tn_is_ml&lt;br /&gt;
&lt;br /&gt;
	if ((target_count = ProcessTargetString(&lt;br /&gt;
			arg1,&lt;br /&gt;
			client,&lt;br /&gt;
			target_list,&lt;br /&gt;
			MAXPLAYERS,&lt;br /&gt;
			COMMAND_FILTER_ALIVE, /* Only allow alive players */&lt;br /&gt;
			target_name,&lt;br /&gt;
			sizeof(target_name),&lt;br /&gt;
			tn_is_ml)) &amp;lt;= 0)&lt;br /&gt;
	{&lt;br /&gt;
		/* This function replies to the admin with a failure message */&lt;br /&gt;
		ReplyToTargetError(client, target_count);&lt;br /&gt;
		return Plugin_Handled;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	for (new i = 0; i &amp;lt; target_count; i++)&lt;br /&gt;
	{&lt;br /&gt;
		SlapPlayer(target_list[i], damage)&lt;br /&gt;
		LogAction(client, target_list[i], &amp;quot;\&amp;quot;%L\&amp;quot; slapped \&amp;quot;%L\&amp;quot; (damage %d)&amp;quot;, client, target_list[i], damage)&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if (tn_is_ml)&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %t for %d damage!&amp;quot;, target_name, damage)&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		ShowActivity2(client, &amp;quot;[SM] &amp;quot;, &amp;quot;Slapped %s for %d damage!&amp;quot;, target_name, damage)&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;
=Client and Entity Indexes=&lt;br /&gt;
One major point of confusion with Half-Life 2 is the difference between the following things:&lt;br /&gt;
*Client index&lt;br /&gt;
*Entity index&lt;br /&gt;
*Userid&lt;br /&gt;
&lt;br /&gt;
The first answer is that clients are entities.  Thus, a client index and an entity index are the same thing.  When a SourceMod function asks for an entity index, a client index can be specified.  When a SourceMod function asks for a client index, usually it means only a client index can be specified.&lt;br /&gt;
&lt;br /&gt;
A fast way to check if an entity index is a client is checking whether it's between 1 and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=397&amp;amp; GetMaxClients()] (inclusive).  If a server has N client slots maximum, then entities 1 through N are always reserved for clients.  Note that 0 is a valid entity index; it is the world entity (worldspawn).&lt;br /&gt;
&lt;br /&gt;
A userid, on the other hand, is completely different.  The server maintains a global &amp;quot;connection count&amp;quot; number, and it starts at 1.  Each time a client connects, the connection count is incremented, and the client receives that new number as their userid.&lt;br /&gt;
&lt;br /&gt;
For example, the first client to connect has a userid of 2.  If he exits and rejoins, his userid will be 3 (unless another client joins in-between).  Since clients are disconnected on mapchange, their userids change as well.  Userids are a handy way to check if a client's connection status has changed. &lt;br /&gt;
&lt;br /&gt;
SourceMod provides two functions for userids: [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=442&amp;amp; GetClientOfUserId()] and [http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=402&amp;amp; GetClientUserId()].&lt;br /&gt;
&lt;br /&gt;
=Events=&lt;br /&gt;
Events are informational notification messages passed between objects in the server.  Many are also passed from the server to the client.  They are defined in .res files under the &amp;lt;tt&amp;gt;hl2/resource&amp;lt;/tt&amp;gt; folder and &amp;lt;tt&amp;gt;resource&amp;lt;/tt&amp;gt; folders of specific mods.  For a basic listing, see [[Game Events (Source)|Source Game Events]].&lt;br /&gt;
&lt;br /&gt;
It is important to note a few concepts about events:&lt;br /&gt;
*They are almost always informational.  That is, blocking &amp;lt;tt&amp;gt;player_death&amp;lt;/tt&amp;gt; will not stop a player from dying.  It may block a HUD or console message or something else minor.&lt;br /&gt;
*They always use userids instead of client indexes.&lt;br /&gt;
*Just because it is in a resource file does not mean it is ever called, or works the way you expect it to.  Mods are notorious at not properly documenting their event functionality.&lt;br /&gt;
&lt;br /&gt;
An example of finding when a player dies:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   HookEvent(&amp;quot;player_death&amp;quot;, Event_PlayerDeath)&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public Event_PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)&lt;br /&gt;
{&lt;br /&gt;
   new victim_id = GetEventInt(event, &amp;quot;userid&amp;quot;)&lt;br /&gt;
   new attacker_id = GetEventInt(event, &amp;quot;attacker&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
   new victim = GetClientOfUserId(victim_id)&lt;br /&gt;
   new attacker = GetClientOfUserId(attacker_id)&lt;br /&gt;
&lt;br /&gt;
   /* CODE */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Callback Orders and Pairing=&lt;br /&gt;
SourceMod has a number of builtin callbacks about the state of the server and plugin.  Some of these are paired in special ways which is confusing to users.&lt;br /&gt;
&lt;br /&gt;
==Pairing==&lt;br /&gt;
'''Pairing''' is SourceMod terminology.  Examples of it are:&lt;br /&gt;
*OnMapEnd() cannot be called without an OnMapStart(), and if OnMapStart() is called, it cannot be called again without an OnMapEnd().&lt;br /&gt;
*OnClientConnected(N) for a given client N will only be called once, until an OnClientDisconnected(N) for the same client N is called (which is guaranteed to happen).&lt;br /&gt;
&lt;br /&gt;
There is a formal definition of SourceMod's pairing.  For two functions X and Y, both with input A, the following conditions hold:&lt;br /&gt;
*If X is invoked with input A, it cannot be invoked again with the same input unless Y is called with input A.&lt;br /&gt;
*If X is invoked with input A, it is guaranteed that Y will, at some point, be called with input A.&lt;br /&gt;
*Y cannot be invoked with any input A unless X was called first with input A.&lt;br /&gt;
*The relationship is described as, &amp;quot;X is paired with Y,&amp;quot; and &amp;quot;Y is paired to X.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==General Callbacks==&lt;br /&gt;
These callbacks are listed in the order they are called, in the lifetime of a plugin and the server.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=576&amp;amp; AskPluginLoad()] - Called once, immediately after the plugin is loaded from the disk.  &lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=575&amp;amp; OnPluginStart()] - Called once, after the plugin has been fully initialized and can proceed to load.  Any run-time errors in this function will cause the plugin to fail to load.  '''This is paired with OnPluginEnd()'''.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=580&amp;amp; OnMapStart()] - Called every time the map loads.  If the plugin is loaded late, and the map has already started, this function is called anyway after load, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=582&amp;amp; OnConfigsExecuted()] - Called once per map-change after  &amp;lt;tt&amp;gt;servercfgfile&amp;lt;/tt&amp;gt; (usually &amp;lt;tt&amp;gt;server.cfg&amp;lt;/tt&amp;gt;), &amp;lt;tt&amp;gt;sourcemod.cfg&amp;lt;/tt&amp;gt;, and all plugin config files have finished executing.  If a plugin is loaded after this has happened, the callback is called anyway, in order to preserve pairing.  '''This function is paired with OnMapEnd().'''&lt;br /&gt;
*At this point, most game callbacks can occur, such as events and callbacks involving clients (or other things, like OnGameFrame).&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=581&amp;amp; OnMapEnd()] - Called when the map is about to end.  At this point, all clients are disconnected, but &amp;lt;tt&amp;gt;TIMER_NO_MAPCHANGE&amp;lt;/tt&amp;gt; timers are not yet destroyed.  '''This function is paired to OnMapStart().'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=577&amp;amp; OnPluginEnd()] - Called once, immediately before the plugin is unloaded.  '''This function is paired to OnPluginStart().'''&lt;br /&gt;
&lt;br /&gt;
==Client Callbacks==&lt;br /&gt;
These callbacks are listed in no specific order, however, their documentation holds for both fake and real clients.&lt;br /&gt;
&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=388&amp;amp; OnClientConnect()] - Called when a player initiates a connection.  '''This is paired with OnClientDisconnect() for successful connections only.'''&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=394&amp;amp; OnClientAuthorized()] - Called when a player gets a Steam ID.  It is important to note that this may never be called.  It may occur any time in between connect and disconnect.  Do not rely on it unless you are writing something that needs Steam IDs, and even then you should use OnClientPostAdminCheck().&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=389&amp;amp; OnClientPutInServer()] - Signifies that the player is in-game and IsClientInGame() will return true.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=396&amp;amp; OnClientPostAdminCheck()] - Called after the player is '''both authorized and in-game'''.  That is, both OnClientAuthorized() '''and''' OnClientPutInServer() have been invoked.  This is the best callback for checking administrative access after connect.&lt;br /&gt;
*[http://docs.sourcemod.net/api/index.php?fastload=show&amp;amp;id=390&amp;amp; OnClientDisconnect()] - Called when a player's disconnection ends.  '''This is paired to OnClientConnect().'''&lt;br /&gt;
&lt;br /&gt;
=Frequently Asked Questions=&lt;br /&gt;
==Are plugins reloaded every mapchange?==&lt;br /&gt;
Plugins, by default, are not reloaded on mapchange unless their timestamp changes.  This is a feature so plugin authors have more flexibility with the state of their plugins.  &lt;br /&gt;
&lt;br /&gt;
==Do I need to call CloseHandle in OnPluginEnd?==&lt;br /&gt;
No.  SourceMod automatically closes your Handles when your plugin is unloaded, in order to prevent memory errors.&lt;br /&gt;
&lt;br /&gt;
==Do I need to #include every individual .inc?==&lt;br /&gt;
No.  &amp;lt;tt&amp;gt;#include &amp;lt;sourcemod&amp;gt;&amp;lt;/tt&amp;gt; will give you 95% of the .incs.  Similarly, &amp;lt;tt&amp;gt;#include &amp;lt;sdktools&amp;gt;&amp;lt;/tt&amp;gt; includes everything starting with &amp;lt;sdktools&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Why don't some events fire?==&lt;br /&gt;
There is no guarantee that events will fire.  The event listing is not a specification, it is a list of the events that a game is capable of firing.  Whether the game actually fires them is up to Valve or the developer.&lt;br /&gt;
&lt;br /&gt;
==Do I need to CloseHandle timers?==&lt;br /&gt;
No.  In fact, doing so may cause errors.  Timers naturally die on their own unless they are infinite timers, in which case you can use KillTimer() or die gracefully by returning &amp;lt;tt&amp;gt;Plugin_Stop&amp;lt;/tt&amp;gt; in the callback.&lt;br /&gt;
&lt;br /&gt;
==Are clients disconnected on mapchange?==&lt;br /&gt;
All clients are fully disconnected before the map changes.  They are all reconnected after the next map starts.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further reading, see the &amp;quot;Scripting&amp;quot; section at the [http://docs.sourcemod.net/ SourceMod Documentation].&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Category:Ru:SourceMod_Scripting&amp;diff=6727</id>
		<title>Category:Ru:SourceMod Scripting</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Category:Ru:SourceMod_Scripting&amp;diff=6727"/>
		<updated>2008-12-26T13:03:12Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Продвинутый API */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Эта категория содержит статьи о написании скриптов под SourceMod с использованием SourcePawn.&lt;br /&gt;
&lt;br /&gt;
===Введение===&lt;br /&gt;
*[[Ru:Introduction to SourcePawn|Ru:Introduction to SourcePawn]] - Введение в SourcePawn. Обучение синтаксису языка.&lt;br /&gt;
*[[Ru:Introduction to SourceMod Plugins|Ru:Introduction to SourceMod Plugins]] - Введение в SourceMod плагины. Создаем Ваш &amp;quot;первый плагин&amp;quot;.&lt;br /&gt;
*[http://docs.sourcemod.net/api API Reference] - Поиск сценариев в справочнике API.&lt;br /&gt;
&lt;br /&gt;
===Основной API===&lt;br /&gt;
*[[Ru:AutoConfigs (SourceMod Scripting)|Ru:AutoConfigs]] - Автоматическое создание .cfg файлов.&lt;br /&gt;
*[[Ru:Commands (SourceMod Scripting)|Ru:Commands]] - Консольные команды/ввод.&lt;br /&gt;
*[[Ru:ConVars (SourceMod Scripting)|Ru:ConVars]] - Консольные переменные (cvars).&lt;br /&gt;
*[[Ru:Events (SourceMod Scripting)|Ru:Events]] - Игровые события Half-Life.&lt;br /&gt;
*[[Ru:KeyValues (SourceMod Scripting)|Ru:KeyValues]] - KeyValues анализ/запись файла.&lt;br /&gt;
*[[Ru:Menu API (SourceMod)|Ru:Menus]] - Создание и отображение меню.&lt;br /&gt;
*[[Ru:SQL (SourceMod Scripting)|Ru:SQL]] - Использование баз данных (MySQL, SQLite).&lt;br /&gt;
*[[Ru:Timers (SourceMod Scripting)|Ru:Timers]] - Вызов таймеров.&lt;br /&gt;
*[[Ru:Translations (SourceMod Scripting)|Ru:Translations]] - Создание локализаций.&lt;br /&gt;
&lt;br /&gt;
===Продвинутый API===&lt;br /&gt;
*[[Admin API (SourceMod)|Administration API]] - Использование кэша администратора.&lt;br /&gt;
*[[Admin Menu (SourceMod Scripting)|Admin Menu API]] - Закрепление в меню администратора.&lt;br /&gt;
*[[Creating Natives (SourceMod Scripting)|Creating Natives]] - Разоблачение API других плагинов.&lt;br /&gt;
*[[Function Calling API (SourceMod Scripting)|Function Calling API]] - Вызовы внешних функций.&lt;br /&gt;
*[[Optional Requirements (SourceMod Scripting)|Optional Requirements]] - Управление зависимостями.&lt;br /&gt;
*[[SDKTools (SourceMod Scripting)|SDKTools]] - Использование мощного SDK уровней абстракции.&lt;br /&gt;
*[[TempEnts (SourceMod SDKTools)|Temporary Entities]] - Использование временных объектов.&lt;br /&gt;
&lt;br /&gt;
===Информация===&lt;br /&gt;
*[[Deprecation Schedule (SourceMod Scripting)|Deprecation Schedule]] - Which functions are getting removed.&lt;br /&gt;
*[[Format Class Functions (SourceMod Scripting)|Format Class Functions]] - All about text formatting.&lt;br /&gt;
*[[Handles (SourceMod Scripting)|Handles]] - Overview of Handles and some common types.&lt;br /&gt;
*[[Optimizing Plugins (SourceMod Scripting)|Optimizing Plugins]] - Optimization hints.&lt;br /&gt;
*[[Tags (Scripting)|Tags]] - All about tags.&lt;br /&gt;
*[[Vectors Explained (Scripting)|Vectors Explained]] - Explanation of Vector types.&lt;br /&gt;
&lt;br /&gt;
===Дополнительные средства===&lt;br /&gt;
*[http://docs.sourcemod.net/api API Reference] - Searchable scripting API reference.&lt;br /&gt;
*[[Entity Properties]] - Explanation of Source entity properties.&lt;br /&gt;
*[[Game Events (Source)|Game Events]] - Game events listings for popular mods.&lt;br /&gt;
*[[Mod TempEnt List (Source)|Temp Entity Lists]] - Temporary entities for popular mods.&lt;br /&gt;
*[[SourceMod Profiler]] - Performance tracking and optimizing.&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6726</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6726"/>
		<updated>2008-12-26T12:42:50Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Локальный static */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Этот пример НЕ является столь эффективным, как &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
Ключевое слово &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; входит в глобальную и локальную область действия. Оно имеет различные значения в каждой из них.&lt;br /&gt;
&lt;br /&gt;
===Глобальный static===&lt;br /&gt;
Глобальные static переменные могут быть доступны только в рамках того же файла. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если плагин включает в себя оба этих файла, он не сможет использовать &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. Это простой механизм сокрытия информации, и аналогичен элементам объявления переменных, например &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; в таких языках, как C++, Java, или C#.&lt;br /&gt;
&lt;br /&gt;
===Локальный static===&lt;br /&gt;
Локальная static переменная является глобальной переменной, которая является видимой лишь из её местной области действия. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; технически глобальная переменная -- она инициализируется один раз как -1 и никогда не инициализируется заново. Оно не существует в наборе. Это означает, что при каждом запуске функции &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt;, переменная &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; и ее хранение в памяти одно и тоже.&lt;br /&gt;
&lt;br /&gt;
Возьмем следающий пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; может быть &amp;lt;tt&amp;gt;-1 +5 +6 +10&amp;lt;/tt&amp;gt;, или &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, поскольку она сохраняется за рамками этой функции. Это может создавать проблемы для рекурсивной функции: если ваша функция может быть рекурсивной, то &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;, как правило, не является хорошей идеей, если только Ваш код не реентерабельный.&lt;br /&gt;
&lt;br /&gt;
Преимуществом локальных static переменных является то, что Вам не придется загромождать свой сценарий глобальными переменными. До тех пор, пока переменной не нужно читать другую функцию, Вы можете его пихать внутрь функции и её сохранение будет гарантировано.&lt;br /&gt;
&lt;br /&gt;
Заметим, что statics может существовать в любой локальной области действия:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6725</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6725"/>
		<updated>2008-12-26T12:42:00Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Local static */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Этот пример НЕ является столь эффективным, как &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
Ключевое слово &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; входит в глобальную и локальную область действия. Оно имеет различные значения в каждой из них.&lt;br /&gt;
&lt;br /&gt;
===Глобальный static===&lt;br /&gt;
Глобальные static переменные могут быть доступны только в рамках того же файла. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если плагин включает в себя оба этих файла, он не сможет использовать &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. Это простой механизм сокрытия информации, и аналогичен элементам объявления переменных, например &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; в таких языках, как C++, Java, или C#.&lt;br /&gt;
&lt;br /&gt;
===Локальный static===&lt;br /&gt;
Локальная static переменная является глобальной переменной, которая является видимой лишь из её местной области действия. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; технически глобальная переменная -- она инициализируется один раз как -1 и никогда не инициализируется заново. Оно не существует в наборе. Это означает, что при каждом запуске функции &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt;, переменная &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; и ее хранение в памяти одно и тоже.&lt;br /&gt;
&lt;br /&gt;
Возьмем следающий пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; может быть &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, или &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, поскольку она сохраняется за рамки этой функции. Это может создавать проблемы для рекурсивной функции: если ваша функция может быть рекурсивной, то &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt;, как правило, не является хорошей идеей, если только Ваш код не реентерабельный.&lt;br /&gt;
&lt;br /&gt;
Преимуществом локальных static переменных является то, что Вам не придется загромождать свой сценарий глобальными переменными. До тех пор, пока переменной не нужно читать другую функцию, Вы можете его пихать внутрь функции и её сохранение будет гарантировано.&lt;br /&gt;
&lt;br /&gt;
Заметим, что statics может существовать в любой локальной области действия:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6724</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6724"/>
		<updated>2008-12-26T12:27:53Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Global static */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Этот пример НЕ является столь эффективным, как &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
Ключевое слово &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; входит в глобальную и локальную область действия. Оно имеет различные значения в каждой из них.&lt;br /&gt;
&lt;br /&gt;
===Глобальный static===&lt;br /&gt;
Глобальные static переменные могут быть доступны только в рамках того же файла. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если плагин включает в себя оба этих файла, он не сможет использовать &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. Это простой механизм сокрытия информации, и аналогичен элементам объявления переменных, например &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; в таких языках, как C++, Java, или C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6723</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6723"/>
		<updated>2008-12-26T12:27:36Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Global static */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Этот пример НЕ является столь эффективным, как &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
Ключевое слово &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; входит в глобальную и локальную область действия. Оно имеет различные значения в каждой из них.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
Глобальные static переменные могут быть доступны только в рамках того же файла. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если плагин включает в себя оба этих файла, он не сможет использовать &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; или &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;. Это простой механизм сокрытия информации, и аналогичен элементам объявления переменных, например &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; в таких языках, как C++, Java, или C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6722</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6722"/>
		<updated>2008-12-26T12:21:13Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* static */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Этот пример НЕ является столь эффективным, как &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
Ключевое слово &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; входит в глобальную и локальную область действия. Оно имеет различные значения в каждой из них.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6721</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6721"/>
		<updated>2008-12-26T12:18:45Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Notes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Примечания===&lt;br /&gt;
Этот пример НЕ является столь эффективным, как &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Даже несмотря на то, что строка имеет только один символ, оператор &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; гарантирует, что остальная часть массива будет нулевой.&lt;br /&gt;
&lt;br /&gt;
Также обратите внимание, он является неправильным для явной инициализации &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код не будет компилироваться, потому что цель &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, чтобы избежать каких-либо инициализаций.&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6720</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6720"/>
		<updated>2008-12-26T12:10:41Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Golden Rules */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Золотые правила===&lt;br /&gt;
*'''Используйте decl только, если в период объявления и загрузки/чтения значения, Вы абсолютно уверены, что есть по крайней мере одно хранилище/операция, которая отдает переменной действительные данные.'''&lt;br /&gt;
*'''Не оптимизируйте преждевременно.''' Кроме того, нет необходимости использовать &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; на не-массивы, поскольку нет никаких дополнительных затрат на инициализацию однго однострочного значения.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6719</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6719"/>
		<updated>2008-12-26T12:03:32Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Caveats */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Предостережения===&lt;br /&gt;
Обратная сторона &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; состоит в том, что его переменные будут начинаться с &amp;quot;ненужного&amp;quot; содержания. Например, если мы будем использовать:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код может привести к падению сервера, так как массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; может быть полностью испорчен (строки требуют нулевой символ, который может отсутствовать). Точно так же, если мы сделаем:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Значение &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; в настоящее время не определенно. Оно может быть любым значением, отрицательным или положительным.&lt;br /&gt;
&lt;br /&gt;
Заметим, что это легко и эффективно обезопасит строки. Пример ниже показывает, как предотвратить строки от мусора:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6718</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6718"/>
		<updated>2008-12-26T11:51:51Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Explanation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Объяснение===&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом коде, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; равна 5 и &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; равна 0. Во время выполнения этого кода затраты на инициализацию незначительные. Вместе с тем, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; является большим массивом, и затраты на инициализацию всего массива могут быть больше 0 сек. и иметь плохие последствия в определенных ситуациях.&lt;br /&gt;
&lt;br /&gt;
Заметим, что &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; не должен быть нулевой. В период времени с объявления &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; и и перемещения в &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, массив &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; никогда не будет загружен или прочитан. Данный код будет более эффективен, если будет написанный следующим образом:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6717</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6717"/>
		<updated>2008-12-26T11:43:32Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Purpose */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Назначение===&lt;br /&gt;
По умолчанию, все переменные в Pawn будут инициализированы как нуль. Если есть явная инициализация, переменная инициализируется для выражения &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; определенным символам. В локальной области действия, это может потребовать время на выполнение. Ключевое слово &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; (которое действительно только в локальной области действия) было введено, чтобы позволить решать пользователю, хочит ли он инициализировать переменную или нет.&lt;br /&gt;
&lt;br /&gt;
Примечание: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; не должно быть использовано на одну однострочную переменную. Это почти никогда не будет выгодно.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6716</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6716"/>
		<updated>2008-12-26T11:30:46Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Extended Variable Declarations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Расширенное объявление переменных=&lt;br /&gt;
Переменные могут быть объявлены более длинным путем чем просто &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6715</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6715"/>
		<updated>2008-12-26T11:11:05Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Dynamic Arrays */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Динамические массивы=&lt;br /&gt;
Динамические массивы это массивы, которые не имеют фиксированного размера. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Динамические массивы могут иметь любое выражение, соответствующее их размеру до тех пор, пока выражение вычисляется, как число большее чем 0. Как и для обычных массивов, SourcePawn не сможет узнать размер массива после того, как он будет создан; Вы должны задать его, если хотите использовать массив позднее.&lt;br /&gt;
&lt;br /&gt;
Динамические массивы, действительны только в локальной области действия, так как код не может существовать на глобальном уровне.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6714</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6714"/>
		<updated>2008-12-26T10:58:49Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Scope */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Область действия=&lt;br /&gt;
Область действия относится к '''удобочитаемости''' кода. Это означает, что код одного уровня не может быть &amp;quot;виден&amp;quot; в коде другого уровня. Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; имеют '''глобальную область действия'''. Их можно увидеть в любой функции. Вместе с тем, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; в функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; не является той же переменной, как &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; на глобальном уровне. Вместо этого она находится в '''локальной области действия''', и поэтому является '''локально изменяемой'''.&lt;br /&gt;
&lt;br /&gt;
Кроме того, функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; и &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; ничего не знают о существовании других переменных.&lt;br /&gt;
&lt;br /&gt;
Она так же является не только локальной переменной функции &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, но и создается заново каждый раз, когда функция вызывается. Попробуйте представить это:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В приведенном выше примере, функция &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; вызывает сама себя. Конечно, это бесконечной рекурсии (а это очень плохо), но идея заключается в том, что каждый раз, когда функция срабатывает, то создается новая копия &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;. Когда функция завершается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; уничтожается, и её значение теряется.&lt;br /&gt;
&lt;br /&gt;
Это свойство можно объяснить проще тем, что область действия переменной равна уровню её вложенности. То есть, переменная на глобальной области действия видна для всех функций. Переменная в локальной области действия видна всему блоку кода расположенному &amp;quot;ниже&amp;quot; этого уровня. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код является действительным, поскольку в область действия распространяется по всей функции. Однако этот код, работать не будет:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Отметим, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; объявляется в новом блоке кода. Это означает, что &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; доступна только в том блоке кода, в котором была создана (и всем под-блокам вложенных внутри него). Как только блок кода прекращается, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; становится не действительной.&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0.  Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6713</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6713"/>
		<updated>2008-12-26T10:13:26Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* Ключ соответствия */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Оператор выбора==&lt;br /&gt;
Оператор выбора будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, оператор выбора не проваливается. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code.  That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''.  They can be seen by any function.  However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level.  Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked.  Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself.  Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;.  When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in.  That is, a variable at global scope is visible globally to all functions.  A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function.  The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block.  That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within).  As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0.  Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6712</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6712"/>
		<updated>2008-12-26T10:09:49Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* While Loops */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ключ соответствия==&lt;br /&gt;
Ключ соответствия будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, ключи не терпят неудачи. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While циклы==&lt;br /&gt;
While циклы являются менее распространенными, чем for циклы, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for цикл может быть переписан, как while цикл:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for цикл переписан как while цикл:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while циклы, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code.  That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''.  They can be seen by any function.  However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level.  Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked.  Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself.  Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;.  When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in.  That is, a variable at global scope is visible globally to all functions.  A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function.  The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block.  That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within).  As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0.  Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6711</id>
		<title>Ru:Introduction to SourcePawn</title>
		<link rel="alternate" type="text/html" href="https://wiki.alliedmods.net/index.php?title=Ru:Introduction_to_SourcePawn&amp;diff=6711"/>
		<updated>2008-12-26T10:08:41Z</updated>

		<summary type="html">&lt;p&gt;Frenzzy: /* For Loops */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Это руководство призвано дать Вам самые основные представления по основам написания сприптов в SourcePawn. [[Pawn]] это &amp;quot;скриптовый&amp;quot; язык используемый для внедрения функциональности в других программах. Это означает, что это не самостоятельный язык, как C++ или Java, и его элементы будут отличаться в различных приложениях. SourcePawn это вариация языка Pawn используемая в [[SourceMod]].&lt;br /&gt;
&lt;br /&gt;
Это руководство не расскажет Вам как писать SourceMod плагины; оно предназначено для получения общих представлений о синтаксисе и семантике этого языка. Читайте отдельную статью [[Ru:Introduction to SourceMod Plugins]] (Введение в SourceMod плагины), для введения в SourceMod API.&lt;br /&gt;
&lt;br /&gt;
=Введение для новичков=&lt;br /&gt;
Этот раздел создан не для программистов. Если Вы по прежнему в замешательстве, Вы можете прочитать книги о других языках программирования, таких как PHP, Python, или Java, чтобы получить более полное представление о программировании.&lt;br /&gt;
&lt;br /&gt;
==Идентификаторы/Ключевые слова==&lt;br /&gt;
Идентификаторы представляет собой набор букв, цифр и/или нижнего подчеркивания, что представляет собой нечто уникальное. Идентификаторы вводятся с учетом регистра (в отличие от PHP, где иногда это не требуется). Идентификаторы не начинаются с какого-либо специального символа, но они должны начинаться с буквы.&lt;br /&gt;
&lt;br /&gt;
Есть несколько зарезервированных символов, которые имеют особое значение. Например, &amp;lt;tt&amp;gt;if&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;for&amp;lt;/tt&amp;gt;, и &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt; специальные конструкции в языке, которые будут описаны позднее. Они не могут быть использованы в качестве названий идентификаторов.&lt;br /&gt;
&lt;br /&gt;
==Переменные==&lt;br /&gt;
Существует несколько важных конструкций, которые Вы должны знать, прежде чем приступить к написанию сценария. Во-первых, это '''переменные'''. Переменная это идентификатор, который содержит данные. Например, переменная &amp;quot;a&amp;quot; может содержать числа &amp;quot;2&amp;quot;, &amp;quot;16&amp;quot;, &amp;quot;0&amp;quot;, и так далее. Переменные создаются для хранения данных внутри программы. Переменные должны быть объявлены до их использования, с помощью ключевого слова &amp;quot;new&amp;quot;. Данные можно присвоить переменной, используя знак равенства (=). Пример:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, b, c, d;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 16;&lt;br /&gt;
c = 0;&lt;br /&gt;
d = 500;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В SourcePawn, переменные бывают двух типов, которые будут более подробно описаны далее.&lt;br /&gt;
*Однострочные (могут содержать только произвольные числовые данные), как показано выше.&lt;br /&gt;
*Многострочные (могут содержать целый ряд текстовых символов)&lt;br /&gt;
&lt;br /&gt;
==Функции==&lt;br /&gt;
Следующим важным понятием являются '''функции'''. Функции идентификаторов или имен, которые выполняют действия. Это означает, что когда вы их активируете, они выполняют конкретную последовательность кода. Есть несколько типов функций, но все функции активируется одинаковым образом. &amp;quot;Вызов функции&amp;quot; является термином ссылающимся на функцию действия. Функция числовых переменных строятся так:&lt;br /&gt;
&amp;lt;pawn&amp;gt;функция(&amp;lt;параметры&amp;gt;)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Примеры:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;show(56);   //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей число 56&lt;br /&gt;
show();     //Активирует функцию &amp;quot;show&amp;quot; без каких-либо данных, пустую&lt;br /&gt;
show(a);    //Активирует функцию &amp;quot;show&amp;quot; и присваивает ей переменную с данными&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Каждый фрагмент данных передаваемый вызываемой функции, называется '''параметр'''. Функция может иметь любое количество параметров (но есть &amp;quot;допустимый&amp;quot; предел в SourceMod: 32). Параметры будут описаны далее в этой статье.&lt;br /&gt;
&lt;br /&gt;
==Комментарии==&lt;br /&gt;
Примечания и любой текст, который пишется после &amp;quot;//&amp;quot; считается &amp;quot;Комментарием&amp;quot;, а не фактическим кодом. Есть два стиля комментариев:&lt;br /&gt;
*&amp;lt;tt&amp;gt;//&amp;lt;/tt&amp;gt; - Двойная косая черта, всё следующие после этой строки игнорируется.&lt;br /&gt;
*&amp;lt;tt&amp;gt;/* */&amp;lt;/tt&amp;gt; - Много-строчный комментарий, весь текст, внутри звездочек игнорируются. You cannot nest these.&lt;br /&gt;
&lt;br /&gt;
==Массивы==&lt;br /&gt;
Описание массивов. Вы можете группировать код в виде &amp;quot;массивов&amp;quot;, разделенных { и }. Это фактически создает возможность работать с целым массивом как с одним оператором. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;{&lt;br /&gt;
   here;&lt;br /&gt;
   is;&lt;br /&gt;
   some;&lt;br /&gt;
   code;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Массивы с фигурными скобками используются достаточно широко в программировании. Массивы кода могут быть вложенными друг в друга. Это хорошая возможность адаптировать последовательность когда и сделать его удобочитаемым, благодаря отступам код не будет смотреться как одна большая и длинная макаронина.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Особенности языка=&lt;br /&gt;
Pawn может показаться очень похожим на другие языки программирования, например C, но Pawn от них фундаментально отличается. Не столь важно, чтобы Вы сейчас же поняли его отличия, но они понадобятся, если Вы уже знаете один из языков программирования.&lt;br /&gt;
*'''Pawn не печатает''' Pawn имеет только один тип данных - '''однострочный'''. Подробнее будет описано позже. [В дальнейшем автор рассказывает, что существует два типа данных: однострочный и многострочный]&lt;br /&gt;
*'''Pawn не собирает мусор''' Pawn, как язык, не имеет встроенных ресурсов памяти, и потому он не мусорит. Если функция выделит память, то Вы отвечаете за её освобождение.&lt;br /&gt;
*'''Pawn не объектно-ориентированный язык''' Pawn является процедурным, и полагается на подпрограммы. Также у него нету C подобных структур.&lt;br /&gt;
*'''Pawn не функциональный.''' Pawn является процедурным, и не поддерживает функции &amp;quot;лямбды&amp;quot; (Lambda), поздние присвоения, и все то, что можно найти в языках высшего уровня, таких как Phyton и Ruby.&lt;br /&gt;
*'''Pawn однопоточный''' As of this writing, Pawn is not thread safe.  &lt;br /&gt;
*'''Pawn не интерпретируемый''' Ну, почти. Он интерпретируется на очень низком уровне. Вы должны скомпилировать код, из которого получится бинарный файл. Эта программа будет работать на той платформе, которую использует хост. Это ускоряет загрузку и позволяет легче находить ошибки.&lt;br /&gt;
&lt;br /&gt;
Этот язык был выпущен ITB CompuPhase. Язык разработан для устройств низкого уровня и таким образом конечные программы очень маленькие по размеру и очень быстрые.&lt;br /&gt;
&lt;br /&gt;
=Переменные=&lt;br /&gt;
В Pawn есть всего два типа переменных: '''однострочные''' и '''многострочные'''. Однострочные могут содержать 32 бита цифровых данных. Многострочные - последовательный список из UTF-8 символов.&lt;br /&gt;
&lt;br /&gt;
'''однострочные''' не имеет своего типа, однако они могут быть '''маркированы'''(tagged). Тег позволяет Вам указывать, где определенную ячейку можно использовать.  Типичные теги:&lt;br /&gt;
*(пусто), или '''_''' - Нет тега.  Обычно используют для целых чисел ([http://en.wikipedia.org/wiki/Integer Integers]).&lt;br /&gt;
*'''Float''' - используют для чисел с плавающей точкой (небольших).&lt;br /&gt;
*'''bool''' - используют для хранения  значений '''true''' (истина) или '''false''' (ложь).&lt;br /&gt;
&lt;br /&gt;
Со строками все по другому, они будут рассмотрены далее.&lt;br /&gt;
&lt;br /&gt;
==Объявления==&lt;br /&gt;
Примеры разных правильных объявлений переменных.&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&lt;br /&gt;
new Float:b = 5.0;&lt;br /&gt;
new bool:c = true;&lt;br /&gt;
new bool:d = 0;      //Работает, поскольку 0 равно false (ложь)  &lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Неправильные объявления переменных&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5.0;         //Несоответствие тегов. 5.0 с тегом Float&lt;br /&gt;
new Float:b = 5;     //Несоответствие тегов. 5 без тега.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Если переменная не определена в объявлении то ее значения станет 0&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a;        //значение 0&lt;br /&gt;
new Float:b;  //значение 0.0&lt;br /&gt;
new bool:c;   //значение false&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Присвоение==&lt;br /&gt;
Переменным могут быть присвоены данные после создания. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, Float:b, bool:c;&lt;br /&gt;
&lt;br /&gt;
a = 5;&lt;br /&gt;
b = 5.0;&lt;br /&gt;
c = true;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Массивы=&lt;br /&gt;
Массив это последовательность данных в последовательном списке. Массивы очень полезны для хранения нескольких единиц данных в одной переменной, а зачастую могут значительно упростить многие задачи.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
Массив объявляется с помощью квадратных скобок. Вот некоторые примеры массивов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new players[32];     //Набор из 32 однострочных (числовых) данных&lt;br /&gt;
new Float:origin[3]; //Набор из 3 чисел с плавающей точкой&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По умолчанию, массивам присваиваются нули. Вы можете присвоить им разные значения по умолчанию, однако:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5] = {1, 2, 3, 4, 5};       //Набор 1, 2, 3, 4, 5 из однострочных данных.&lt;br /&gt;
new Float:origin[3] = {1.0, 2.0, 3.0};  //Набор 1.0, 2.0, 3.0 из однострочных данных.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы можете оставить массив без размера, если вы собираетесь заранее присвоить ему данные. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[] = {1, 3, 5, 7, 9};&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Компилятор будет автоматически делать вывод о том, что Вы хотите получить массив размером 5.&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Использование массива равносильно использованию обычных переменной. Единственное отличие массива состоит в том, что он должен быть '''индексируемым'''. Индексирование массива означает присутствие возможности выбрать элемент, который Вы хотите использовать.&lt;br /&gt;
&lt;br /&gt;
Вот пример кода с использованием индексов:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5], Float:origin[3];&lt;br /&gt;
&lt;br /&gt;
numbers[0] = 1;&lt;br /&gt;
numbers[1] = 2;&lt;br /&gt;
numbers[2] = 3;&lt;br /&gt;
numbers[3] = 4;&lt;br /&gt;
numbers[4] = 5;&lt;br /&gt;
origin[0] = 1.0;&lt;br /&gt;
origin[1] = 2.0;&lt;br /&gt;
origin[2] = 3.0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что '''индекс''' это текст, который находится в квадратных скобках. Индекс всегда начинается с нуля. То есть, если массив имеет N элементов, его действительный индекс от 0 до N-1. Доступ к данным с индексами работает так же, как с обычной переменной.&lt;br /&gt;
&lt;br /&gt;
Использование неверного индекса вызовет ошибку. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new numbers[5];&lt;br /&gt;
&lt;br /&gt;
numbers[5] = 20;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это может выглядеть верно, но число 5 не является допустимым индексом. Наибольшим значением индекса является число 4.&lt;br /&gt;
&lt;br /&gt;
Вы можете использовать любые выражения, как индекс. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a, numbers[5];&lt;br /&gt;
&lt;br /&gt;
a = 1;                   //Сделает a = 1&lt;br /&gt;
numbers[a] = 4;          //Сделает numbers[1] = 4&lt;br /&gt;
numbers[numbers[a]] = 2; //Сделает numbers[4] = 2&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Выражения будут обсуждаться подробнее в конце статьи.&lt;br /&gt;
&lt;br /&gt;
=Строки=&lt;br /&gt;
Строки являются удобным способом хранения текста. Символы хранятся в массиве. Строка ограничивается '''нулевым символом''', или 0. Без нулевого символа, Pawn не знает, где остановить чтение строки. Все строки в SourcePawn используют кодировку UTF-8.&lt;br /&gt;
&lt;br /&gt;
Отметим, что строки имеют комбинацию из массивов и однострочных переменных. В отличие от других языков, это означает, что Вы должны знать заранее, как много места будут использовать строки. Это означает, что строки не являются динамичными. Они могут лишь вырасти до размера, которым Вы их ограничили.&lt;br /&gt;
&lt;br /&gt;
''Примечание для специалистов: они фактически не однострочные. SourcePawn использует 8-битный строки для хранения массивов в качестве оптимизации. Это и есть то, что делает строки типом, а не меткой.''&lt;br /&gt;
&lt;br /&gt;
==Использование==&lt;br /&gt;
Строки были созданы почти в равной степени и для массивов. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[] = &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
new String:clams[6] = &amp;quot;Clams&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это равносильно следующему:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:message[7], String:clams[6];&lt;br /&gt;
&lt;br /&gt;
message[0] = 'H';&lt;br /&gt;
message[1] = 'e';&lt;br /&gt;
message[2] = 'l';&lt;br /&gt;
message[3] = 'l';&lt;br /&gt;
message[4] = 'o';&lt;br /&gt;
message[5] = '!';&lt;br /&gt;
message[6] = 0;&lt;br /&gt;
clams[0] = 'C';&lt;br /&gt;
clams[1] = 'l';&lt;br /&gt;
clams[2] = 'a';&lt;br /&gt;
clams[3] = 'm';&lt;br /&gt;
clams[4] = 's';&lt;br /&gt;
clams[5] = 0;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя строки редко инициализируют таким образом, очень важно помнить о концепции нулевого символа, который свидетельствует о конце строки. Компилятор и большинство SourceMod функций будут автоматически остановлены нулевым символом, поэтому он является очень важным, при манипулировании строками напрямую.&lt;br /&gt;
&lt;br /&gt;
Заметим, что строка должна быть заключена в двойных кавычках, а символ в одиночных.&lt;br /&gt;
&lt;br /&gt;
==Символы==&lt;br /&gt;
Особенность текста может быть использована в любой строке или однострочной переменной. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new String:text[] = &amp;quot;Crab&amp;quot;;&lt;br /&gt;
new clam;&lt;br /&gt;
&lt;br /&gt;
clam = 'D';         //Устанавливает однострочной переменной значение 'D'&lt;br /&gt;
text[0] = 'A';      //Меняет 'C' на 'A', сейчас получилось 'Arab'&lt;br /&gt;
clam = text[0];     //Устанавливает однострочной переменной значение 'A'&lt;br /&gt;
text[1] = clam;     //Меняет 'r' на 'A', сейчас получилось 'AAab'&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
То, что вы не можете сделать, это соотнести символы массивов со строками. Внутреннее хранение отличается. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new clams[] = &amp;quot;Clams&amp;quot;;                       //Не верно, нужен тип String:&lt;br /&gt;
new clams[] = {'C', 'l', 'a', 'm', 's', 0};  //Верно, но это НЕ СТРОКА.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Функции=&lt;br /&gt;
Функции, как отмечалось ранее, имеют отдельные составляющие кода, которые выполняют определенные действия. Функции могут быть задействованы или '''вызвоны''' с '''параметрами''', которые дают особые настройки.&lt;br /&gt;
&lt;br /&gt;
Существуют два типа вызова функции:&lt;br /&gt;
*'''прямой вызов''' - Вы специально вызываете функцию в своем коде.&lt;br /&gt;
*'''обратный вызов''' - Применение вызова функций в Вашем коде, как если бы это было событием триггера (совокупность условий, инициирующих выполнение действия).&lt;br /&gt;
&lt;br /&gt;
Существуют пять видов функций:&lt;br /&gt;
*'''native''': Прямая, внутренняя функция, предусмотренная в приложении.&lt;br /&gt;
*'''public''': Функция обратного вызова, что делает её видимой для приложения и других сценариев.&lt;br /&gt;
*'''normal''': Нормальная функция, которую Вы можете только вызвать.&lt;br /&gt;
*'''stock''': Нормальная функция, предусмотренная если включает в себя файл. Если не используется, то не компилируется.&lt;br /&gt;
*'''forward''': Эта функция представляет собой глобальное событие, предусмотренная приложением. Если Вы её привели в исполнение, она будет вызвона.&lt;br /&gt;
&lt;br /&gt;
Весь код в Pawn должен существовать в функциях. Это основное отличие от языков, таких как PHP, Perl и Python, которые позволяют Вам писать глобальный код. Это происходит потому, что Pawn вызывается на основе другого языка: он реагирует на действия от родительского приложения, и функции должны быть написаны для обработки этих действий. Хотя наш пример, часто содержат свободно плавающий код, это сделано исключительно для демонстрационных целей. Свободно плавающий код в нашем примере означает, что код является частью ряда функций.&lt;br /&gt;
&lt;br /&gt;
==Описание==&lt;br /&gt;
В отличие от переменных, функции, не нужно объявлять, прежде чем использовать их. Функции имеют две части, '''модель''' и '''тело'''. Модель содержит имя Вашей функции и параметры, которые она будет принимать. Тело является контейнером для кода.&lt;br /&gt;
&lt;br /&gt;
Пример функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
AddTwoNumbers(first, second)&lt;br /&gt;
{&lt;br /&gt;
  new sum = first + second;&lt;br /&gt;
&lt;br /&gt;
  return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это простая функция. Модель этой строки:&lt;br /&gt;
&amp;lt;pawn&amp;gt;AddTwoNumbers(first, second)&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Распишем по отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;AddTwoNumbers&amp;lt;/tt&amp;gt; - Название функции.&lt;br /&gt;
*&amp;lt;tt&amp;gt;first&amp;lt;/tt&amp;gt; - Название первого параметра, который представляет собой простой элемент.&lt;br /&gt;
*&amp;lt;tt&amp;gt;second&amp;lt;/tt&amp;gt; - Название второго параметра, который представляет собой простой элемент.&lt;br /&gt;
&lt;br /&gt;
Тело представляет собой простой блок кода. Он создает новую переменную, названную &amp;lt;tt&amp;gt;sum&amp;lt;/tt&amp;gt;, и присваивает ей значение этих двух параметров, добавленных совместно (другие выражения будут позже). Важно заметить оператор &amp;lt;tt&amp;gt;return&amp;lt;/tt&amp;gt;, в котором обозначается конец функции и возврат с полученными значениями из этой функции. Все функции ''возвращают значения'' после завершения. Это означает, например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new sum = AddTwoNumbers(4, 5);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведенный выше код будет присваивать число 9 к sum. Функция получает два значения и передает новое значение sum в качестве '''возвращаемого значения'''. Если функция не имеет возвращаемого значения или не имеет значений для возврата, то возвращается 0 по умолчанию.&lt;br /&gt;
&lt;br /&gt;
Функция может принимать любые типы значений. Она может вернуть любую однострочную переменную, но не массивы или строки. Пример:&lt;br /&gt;
&amp;lt;pawn&amp;gt;Float:AddTwoFloats(Float:a, Float:b)&lt;br /&gt;
{&lt;br /&gt;
   new Float:sum = a + b;&lt;br /&gt;
 &lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Заметим, что если в приведенной выше функции, Вам вернулась не Float значение, Вы получите не соответствие значений.''&lt;br /&gt;
&lt;br /&gt;
Можно, конечно, передавать переменные в функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new numbers[3] = {1, 2, 0};&lt;br /&gt;
&lt;br /&gt;
numbers[2] = AddTwoNumbers(numbers[0], numbers[1]);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что однострочные переменные передаются '''по значению'''. То есть, их значение не может быть изменено функцией. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
ChangeValue(a);&lt;br /&gt;
&lt;br /&gt;
ChangeValue(b)&lt;br /&gt;
{&lt;br /&gt;
   b = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Этот код не будет менять значение &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt;. Это происходит потому, что копия этого значения в &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; передается вместо &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; самостоятельно.&lt;br /&gt;
&lt;br /&gt;
Больше примеров функций будут демонстрироваться и в других частях статьи.&lt;br /&gt;
&lt;br /&gt;
==Publics==&lt;br /&gt;
Публичные функции используются для осуществления обратных вызовов. Вы не должны создавать какую-либо публичную функцию, если это вынудит выполнение обратного вызова. Например, вот два обратных вызова из &amp;lt;tt&amp;gt;sourcemod.inc&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;forward OnPluginStart();&lt;br /&gt;
forward OnClientDisconnected(client);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Чтобы выполнить и получить эти два события, Вы должны написать такие функции как:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;public OnPluginStart()&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
public OnClientDisconnected(client)&lt;br /&gt;
{&lt;br /&gt;
   /* Код здесь */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ключевое слово '''public''' делает функцию публичной, а также позволяет родительскому приложению непосредственно вызывать функцию.&lt;br /&gt;
&lt;br /&gt;
==Natives==&lt;br /&gt;
Natives имеют встроенные функции, предоставляемые приложением. Вы можете вызвать их, как если бы они были normal функциями. Например, SourceMod имеет следующие функции:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;native FloatRound(Float:num);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Её можно вызвать таким образом:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new num = FloatRound(5.2);     //Результат в num = 5&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Параметры массива==&lt;br /&gt;
Вы можете передавать массивы или строки в качестве параметров. Важно отметить, что они идут '''как ссылка'''. То есть не делать копию данных, а отдавать непосредственно ссылки на данные. Существует простой способ объяснить это более конкретно.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new example[] = {1, 2, 3, 4, 5};&lt;br /&gt;
&lt;br /&gt;
ChangeArray(example, 2, 29);&lt;br /&gt;
&lt;br /&gt;
ChangeArray(array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Эта функция устанавливает заданный индекс в массиве с учетом значений. Когда она запускается на примере нашего массива, она меняет индекс 2 для значения 3 на 29. То есть:&lt;br /&gt;
&amp;lt;pawn&amp;gt;example[2] = 29;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это возможно лишь потому, что массив может быть непосредственно изменён. Чтобы предотвратить массив от изменения, можно пометить его как постоянную &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt;. Это позволит понизить риск на ошибку в коде от её изменения. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;CantChangeArray(const array[], index, value)&lt;br /&gt;
{&lt;br /&gt;
   array[index] = value;    //Не компилируется&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это хорошая идея использовать &amp;lt;tt&amp;gt;const&amp;lt;/tt&amp;gt; в параметрах массивов и Вы будете точно знать, что массив не будет изменен; это может предотвратить ошибки кодирования.&lt;br /&gt;
&lt;br /&gt;
=Выражения=&lt;br /&gt;
Выражения являются точно такими же, какими они существуют в математике. Это группы операторов/символов, которые приходятся на один фрагмент данных. Они часто заключены в скобках (внутри скобок). Они содержат строгий &amp;quot;порядок операций&amp;quot;. Они могут содержать переменные, функции, цифры и выражения сами могут быть вложенные внутрь других выражений, и даже приняты в качестве параметров.&lt;br /&gt;
&lt;br /&gt;
Приведем пример простейшего выражения:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
0;   //Возвращает число 0&lt;br /&gt;
(0); //Так же возвращает число 0&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Хотя выражения могут возвращать значения, они также могут ответить какое значение содержит ответ ''ноль или не ноль''. В этом смысле, ''ноль'' является ''ложью'' (false), а ''не нулевое'' значение ''истиной'' (true). Например, -1 ''истина'' в Pawn, поскольку она не является нулем. Не думайте, что отрицательные числа являются ложными.&lt;br /&gt;
&lt;br /&gt;
Порядок операций выражения аналогичен языку C. PMDAS: Parenthesis, Multiplication, Division, Addition, Subtraction. Вот несколько примеров выражений:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
5 + 6;                   //Вычисляет как 11&lt;br /&gt;
5 * 6 + 3;               //Вычисляет как 33&lt;br /&gt;
5 * (6 + 3);             //Вычисляет как 45&lt;br /&gt;
5.0 + 2.3;               //Вычисляет как 7.3&lt;br /&gt;
(5 * 6) % 7;             //Modulo operator, вычисляет как 2&lt;br /&gt;
(5 + 3) / 2 * 4 - 9;     //Вычисляет как 7&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Как уже отмечалось, выражения могут содержать переменные, или даже функции:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5 * 6;&lt;br /&gt;
new b = a * 3;      //Вычисляет как 90&lt;br /&gt;
new c = AddTwoNumbers(a, b) + (a * b);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Операторы==&lt;br /&gt;
Есть несколько полезных дополнительных операторов в Pawn. Первый набор упрощает аутоагрегацию выражения. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
&lt;br /&gt;
a = a + 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть переписан, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
a += 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Это верно в отношении следующих операторов в Pawn:&lt;br /&gt;
*Four-function: *, /, -, +&lt;br /&gt;
*Bit-wise: |, &amp;amp;, ^, ~, &amp;lt;&amp;lt;, &amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Кроме того, существуют инкремент/декремент операторы:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a = a + 1;&lt;br /&gt;
a = a - 1;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Может быть упрощено, как:&lt;br /&gt;
&amp;lt;pawn&amp;gt;a++;&lt;br /&gt;
a--;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Дополнительно отметим, что ++ или -- может быть представлен до переменной (до-инкремент, до-декремент) или после переменной (пост-инкремент, пост-декремент). Разница заключается в том, как остальная часть выражения содержащие их, видит результат.&lt;br /&gt;
&lt;br /&gt;
* ''До:'' Переменная увеличивается до определения и остальная часть выражения видит новое значение.&lt;br /&gt;
* ''Пост:'' Переменная увеличивается после определения и остальная часть выражения видит старое значение.&lt;br /&gt;
&lt;br /&gt;
Иными словами, &amp;lt;tt&amp;gt;a++&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; в то время как &amp;lt;tt&amp;gt;++a&amp;lt;/tt&amp;gt; определяет значение как &amp;lt;tt&amp;gt;a + 1&amp;lt;/tt&amp;gt;. В обоих случаях &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; увеличивается на &amp;lt;tt&amp;gt;1&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;new a = 5;&lt;br /&gt;
new b = a++;   // b = 5, a = 6  (1)&lt;br /&gt;
new c = ++a;   // a = 7, c = 7  (2)&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(1) &amp;lt;tt&amp;gt;b&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; со ''старым'' значением, ''до'' того, как он будет увеличено до &amp;lt;tt&amp;gt;6&amp;lt;/tt&amp;gt;. (2) &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; присваивается &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; с ''новым'' значением, ''после'' того, как он увеличивается до &amp;lt;tt&amp;gt;7&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Операторы сравнения==&lt;br /&gt;
Существуют шесть операторов для сравнения двух числовых значений, а результат является либо истиной (не ноль) или ложью (ноль):&lt;br /&gt;
*&amp;lt;tt&amp;gt;a == b&amp;lt;/tt&amp;gt; - Действительно, если и b имеет то же значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a != b&amp;lt;/tt&amp;gt; - Действительно, если b имеет другое значение.&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt; b&amp;lt;/tt&amp;gt; - Действительно, если оно больше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;gt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно больше или равно b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt; b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше b&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;lt;= b&amp;lt;/tt&amp;gt; - Действительно, если оно меньше или равно b&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 != 3);         //Определяется как истина, поскольку 1 не равно 3.&lt;br /&gt;
(3 + 3 == 6);     //Определяется как истина, поскольку 3+3 равно 6.&lt;br /&gt;
(5 - 2 &amp;gt;= 4);     //Определяется как ложь, поскольку 3 меньше 4.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Заметим, что эти операторы не работают с массивами и строками. То есть, вы не можете сравнить их с помощью &amp;lt;tt&amp;gt;==&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Действительные операторы==&lt;br /&gt;
Действительные операторы могут быть скомбинированы тремя булевыми (boolean) операторами:&lt;br /&gt;
*&amp;lt;tt&amp;gt;a &amp;amp;&amp;amp; b&amp;lt;/tt&amp;gt; - Истина, если a и b истинные. Ложь, если a и (или) b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;amp;&amp;amp;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 0&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;a || b&amp;lt;/tt&amp;gt; - Истина, если a или b (или обе переменные) истинные. Ложь, если обе переменные a и b ложные.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;||&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|-&lt;br /&gt;
! 0&lt;br /&gt;
| 0 || 1&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 1 || 1&lt;br /&gt;
|}&lt;br /&gt;
*&amp;lt;tt&amp;gt;!a&amp;lt;/tt&amp;gt; - Истина, если a ложь. Ложь, если a истина.&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; cellspacing=&amp;quot;0&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! &amp;lt;tt&amp;gt;!&amp;lt;/tt&amp;gt; !! 0 !! 1&lt;br /&gt;
|- &lt;br /&gt;
!&lt;br /&gt;
| 1 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
(1 || 0);         //Определяется как истина, так как выражение 1 истинное&lt;br /&gt;
(1 &amp;amp;&amp;amp; 0);         //Определяется как ложь, так как выражение 0 ложное&lt;br /&gt;
(!1 || 0);        //Определяется как ложь, так как выражение !1 ложное.&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Левое/правое значения==&lt;br /&gt;
Два важных понятия левого и правого значений, или левостороннее и правостороннее значения. Левостороннее значение имеет то, что появляется на левой стороне выражения, а правостороннее значение - появляется на правой стороне выражения.&lt;br /&gt;
&lt;br /&gt;
Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new a = 5;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В этом примере &amp;lt;tt&amp;gt;a&amp;lt;/tt&amp;gt; является левосторонним значением и &amp;lt;tt&amp;gt;5&amp;lt;/tt&amp;gt; является правосторонним значением.&lt;br /&gt;
&lt;br /&gt;
Правила:&lt;br /&gt;
*'''Выражения никогда не будут левосторонними значениями'''.&lt;br /&gt;
*'''Переменные являются двумя, левосторонними и правосторонними значениями'''.&lt;br /&gt;
&lt;br /&gt;
=Условия=&lt;br /&gt;
Условия позволяют Вам запускать код, определенное условие выполнено.&lt;br /&gt;
&lt;br /&gt;
==Если соответствует==&lt;br /&gt;
Если соответствует одно или более условий. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код будет запущен, если условие будет истинным */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Они могут быть расширены для более сложных случаев:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 6)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else if (a == 7)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вы так же можете обрабатывать случаи, даже если выражение не верно. Например:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
if (a == 5)&lt;br /&gt;
{&lt;br /&gt;
   /* Код */&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
   /* Код, который будет запущен если нет истинного выражения */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Ключ соответствия==&lt;br /&gt;
Ключ соответствия будет ограничен условием. Он необходим для выражения, выполняющего код для целого ряда возможных значений. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
switch (a)&lt;br /&gt;
{&lt;br /&gt;
   case 5:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 6:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 7:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   case 8, 9, 10:&lt;br /&gt;
   {&lt;br /&gt;
      /* Код */&lt;br /&gt;
   }&lt;br /&gt;
   default:&lt;br /&gt;
   {&lt;br /&gt;
      /* будет запущен, если не одно условие не соответствует */&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
В отличие от некоторых других языков, ключи не терпят неудачи. То есть существуют случаи, когда код не будет запущен. При случае совпадения его код выполняется, а ключ является местом для немедленного прекращения.&lt;br /&gt;
&lt;br /&gt;
=Циклы=&lt;br /&gt;
Циклы позволяют Вам без труда повторять выполнение кода, пока условие станет истинным.&lt;br /&gt;
&lt;br /&gt;
==For циклы==&lt;br /&gt;
For циклы, это циклы, которые состоят из четырех частей:&lt;br /&gt;
*Оператор '''инициализации''' - запускается один раз перед первым циклом.&lt;br /&gt;
*Оператор '''условия''' - проверяет условие и запускает следующий цикл, в том числе первый. Цикл прекращается, когда это выражение становится ложным.&lt;br /&gt;
*Оператор '''итерации''' - запускается после каждого цикла.&lt;br /&gt;
* '''тело''' цикла - запускается каждый раз, пока оператор '''условия''' вычисляется как истинный.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
for ( /* инициализация */ ; /* условие */ ; /* итерация */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Простым примером является функция сложения массива:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};&lt;br /&gt;
new sum = SumArray(array, 10);&lt;br /&gt;
&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total;&lt;br /&gt;
&lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
По отдельности:&lt;br /&gt;
*&amp;lt;tt&amp;gt;new i = 0&amp;lt;/tt&amp;gt; - Создает новую переменную для цикла, и устанавливает её в 0.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i &amp;lt; count&amp;lt;/tt&amp;gt; - Только запускает цикл, если &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; меньше, чем &amp;lt;tt&amp;gt;count&amp;lt;/tt&amp;gt;. Это гарантирует, что чтение цикла прекращается в определенный момент. В этом случае, мы не хотим читать недействительные индексы в массиве.&lt;br /&gt;
*&amp;lt;tt&amp;gt;i++&amp;lt;/tt&amp;gt; - Увеличивает &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; на единицу после каждого цикла. Это гарантирует, что цикл не будет запущен вечно; в конце концов &amp;lt;tt&amp;gt;i&amp;lt;/tt&amp;gt; станет слишком большим, и цикл завершится.&lt;br /&gt;
&lt;br /&gt;
Таким образом, функция &amp;lt;tt&amp;gt;SumArray&amp;lt;/tt&amp;gt; будет циклом каждого действительного индекса массива, каждый раз добавляя это значение в sum. Для циклов очень распространены массивы такие, как в нашем примере.&lt;br /&gt;
&lt;br /&gt;
==While Loops==&lt;br /&gt;
While Loops являются менее распространенными, чем for loops, но на самом деле это более простые циклы. Они имеют только две части:&lt;br /&gt;
*Оператор '''условия''' - проверяется перед началом каждого цикла. Цикл прекращается, когда условие становится ложным.&lt;br /&gt;
*'''тело''' цикла - запускается каждый раз пока цикл выполняется.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
До тех пор, пока условие выражения остается истинным, цикл будет выполняться. Каждый for loop может быть переписан, как while loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/* инициализация */&lt;br /&gt;
while ( /* условие */ )&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
   /* итерация */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Вот предыдущий for loop переписан как while loop:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumArray(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new total, i;&lt;br /&gt;
&lt;br /&gt;
   while (i &amp;lt; count)&lt;br /&gt;
   {&lt;br /&gt;
      total += array[i];&lt;br /&gt;
      i++;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return total;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существуют также '''do...while''' циклы, которые используются еще реже. Они работают как и while loops, но проверяют условие ПОСЛЕ каждого цикла, а не перед ним. Это означает, что цикл всегда будет запущен, по крайней мере один раз. Например:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
do&lt;br /&gt;
{&lt;br /&gt;
   /* тело */&lt;br /&gt;
}&lt;br /&gt;
while ( /* условие */ );&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Управление циклами==&lt;br /&gt;
Существуют два случая, в которых Мы хотели бы контролировать цикл:&lt;br /&gt;
*'''пропустить''' одну итерацию или цикл и продолжить выполнение цикла как обычно, или;&lt;br /&gt;
*'''разорвать''' цикл целиком, прежде чем он закончится.&lt;br /&gt;
&lt;br /&gt;
Допустим у вас есть функция, которая принимает массив и ищет соответствия цифр. Вы хотите его остановить, когда число будет найдено:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * Возвращает массив, если индекс значения, или -1, не найдены.&lt;br /&gt;
 */&lt;br /&gt;
SearchInArray(const array[], count, value)&lt;br /&gt;
{&lt;br /&gt;
   new index = -1;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      if (array[i] == value)&lt;br /&gt;
      {&lt;br /&gt;
         index = i;&lt;br /&gt;
         break;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return index;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Конечно, эту функцию можно вернуть и способом &amp;lt;tt&amp;gt;return i&amp;lt;/tt&amp;gt;, но пример показывает, как &amp;lt;tt&amp;gt;break&amp;lt;/tt&amp;gt; может остановить цикл.&lt;br /&gt;
&lt;br /&gt;
Кроме того, ключевое слово &amp;lt;tt&amp;gt;continue&amp;lt;/tt&amp;gt; пропускает итерации цикла. Например, Мы хотим суммировать все четные числа:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
SumEvenNumbers(const array[], count)&lt;br /&gt;
{&lt;br /&gt;
   new sum;&lt;br /&gt;
 &lt;br /&gt;
   for (new i = 0; i &amp;lt; count; i++)&lt;br /&gt;
   {&lt;br /&gt;
      /* If divisibility by 2 is 1, we know it's odd */&lt;br /&gt;
      if (array[i] % 2 == 1)&lt;br /&gt;
      {&lt;br /&gt;
         /* Пропускаем оставшуюся часть итерации цикла */&lt;br /&gt;
         continue;&lt;br /&gt;
      }&lt;br /&gt;
      sum += array[i];&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   return sum;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Scope=&lt;br /&gt;
Scope refers to the '''visibility''' of code.  That is, code at one level may not be &amp;quot;visible&amp;quot; to code at another level.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new A, B, C;&lt;br /&gt;
&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function2();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Function2()&lt;br /&gt;
{&lt;br /&gt;
   new C;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;A&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;C&amp;lt;/tt&amp;gt; exist at '''global scope'''.  They can be seen by any function.  However, the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; is not the same variable as the &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; at the global level.  Instead, it is at '''local scope''', and is thus a '''local variable'''.&lt;br /&gt;
&lt;br /&gt;
Similarly, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;Function2&amp;lt;/tt&amp;gt; know nothing about each other's variables.&lt;br /&gt;
&lt;br /&gt;
Not only is the variable private to &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt;, but it is re-created each time the function is invoked.  Imagine this:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new B;&lt;br /&gt;
&lt;br /&gt;
   Function1();&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the above example, &amp;lt;tt&amp;gt;Function1&amp;lt;/tt&amp;gt; calls itself.  Of course, this is infinite recursion (a bad thing), but the idea is that each time the function runs, there is a new copy of &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt;.  When the function ends, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is destroyed, and the value is lost.&lt;br /&gt;
&lt;br /&gt;
This property can be simplified by saying that a variable's scope is equal to the nesting level it is in.  That is, a variable at global scope is visible globally to all functions.  A variable at local scope is visible to all code blocks &amp;quot;beneath&amp;quot; its nesting level.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      A = 5;&lt;br /&gt;
   }&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code is valid since A's scope extends throughout the function.  The following code, however, is not valid:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
Function1()&lt;br /&gt;
{&lt;br /&gt;
   new A;&lt;br /&gt;
&lt;br /&gt;
   if (A)&lt;br /&gt;
   {&lt;br /&gt;
      new B = 5;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   B = 5;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is declared in a new code block.  That means &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is only accessible to that code block (and all sub-blocks nested within).  As soon as the code block terminates, &amp;lt;tt&amp;gt;B&amp;lt;/tt&amp;gt; is no longer valid.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Dynamic Arrays=&lt;br /&gt;
Dynamic arrays are arrays which don't have a hardcoded size.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;Function1(size)&lt;br /&gt;
{&lt;br /&gt;
   new array[size];&lt;br /&gt;
&lt;br /&gt;
   /* Code */&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays can have any expression as their size as long as the expression evaluates to a number larger than 0.  Like normal arrays, SourcePawn does not know the array size after it is created; you have to save it if you want it later.&lt;br /&gt;
&lt;br /&gt;
Dynamic arrays are only valid at the local scope level, since code cannot exist globally.&lt;br /&gt;
&lt;br /&gt;
=Extended Variable Declarations=&lt;br /&gt;
Variables can be declared in more ways than simply &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==decl==&lt;br /&gt;
===Purpose===&lt;br /&gt;
By default, all variables in Pawn are initialized to zero.  If there is an explicit initializer, the variable is initialized to the expression after the &amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt; token.  At a local scope, this can be a run-time expense.  The &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; keyword (which is only valid at local scope) was introduced to let users decide if they want variables initialized or not.&lt;br /&gt;
&lt;br /&gt;
Note: &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; should not be used on single cell variables.  There is almost never any benefit.&lt;br /&gt;
&lt;br /&gt;
===Explanation===&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
new String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this code, &amp;lt;tt&amp;gt;c&amp;lt;/tt&amp;gt; is equal to 5 and &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is equal to 0.  The run-time expense of this initialization is negligible.  However, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is a large array, and the expense of initializing the entire array to 0s could be detrimental in certain situations.  &lt;br /&gt;
&lt;br /&gt;
Note that &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; does not need to be zeroed.  In between being declared with &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; and stored with &amp;lt;tt&amp;gt;Format()&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; is never loaded or read.  Thus this code would be more efficiently written as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Caveats===&lt;br /&gt;
The downside to &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is that it means its variables will start with &amp;quot;garbage&amp;quot; contents.  For example, if we were to use:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
new d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
PrintToServer(&amp;quot;%s&amp;quot;, blah);&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code may crash the server, because &amp;lt;tt&amp;gt;blah&amp;lt;/tt&amp;gt; may be completely corrupt (strings require a terminator, and that may not be present).  Similarly, if we did:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new c = 5;&lt;br /&gt;
decl d;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
Format(blah, sizeof(blah), &amp;quot;%d %d&amp;quot;, c, d);&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value of &amp;lt;tt&amp;gt;d&amp;lt;/tt&amp;gt; is now undefined.  It could be any value, negative or positive.  &lt;br /&gt;
&lt;br /&gt;
Note that it is easy to efficiently make strings safe.  The example below shows how to terminate a garbage string:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
decl String:blah[512];&lt;br /&gt;
&lt;br /&gt;
blah[0] = '\0';&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Golden Rules===&lt;br /&gt;
*'''Only use decl if in between declaring and loading/reading the value, you are absolutely sure there is at least one store/set operation that gives the variable valid data.'''&lt;br /&gt;
*'''Do not prematurely optimize.'''  Likewise, there is no need to use &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; on non-arrays, because there is no added expense for initializing a single cell value.&lt;br /&gt;
&lt;br /&gt;
===Notes===&lt;br /&gt;
This example is NOT as efficient as a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
new String:blah[512] = &amp;quot;a&amp;quot;;&lt;br /&gt;
&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though the string is only one character, the &amp;lt;tt&amp;gt;new&amp;lt;/tt&amp;gt; operator guarantees the rest of the array will be zeroed as well.&lt;br /&gt;
&lt;br /&gt;
Also note, it is invalid to explicitly initialize a &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt;:&lt;br /&gt;
&amp;lt;pawn&amp;gt;decl String:blah[512] = &amp;quot;a&amp;quot;;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will not compile, because the purpose of &amp;lt;tt&amp;gt;decl&amp;lt;/tt&amp;gt; is to avoid any initialization.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==static==&lt;br /&gt;
The &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; keyword is available at global and local scope.  It has different meanings in each.&lt;br /&gt;
&lt;br /&gt;
===Global static===&lt;br /&gt;
A global static variable can only be accessed from within the same file.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;//file1.inc&lt;br /&gt;
static Float:g_value1 = 0.15f;&lt;br /&gt;
&lt;br /&gt;
//file2.inc&lt;br /&gt;
static Float:g_value2 = 0.15f;&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If a plugin includes both of these files, it will not be able to use either &amp;lt;tt&amp;gt;g_value1&amp;lt;/tt&amp;gt; or &amp;lt;tt&amp;gt;g_value2&amp;lt;/tt&amp;gt;.  This is a simple information hiding mechanism, and is similar to declaring member variables as &amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; in languages like C++, Java, or C#.&lt;br /&gt;
&lt;br /&gt;
===Local static===&lt;br /&gt;
A local static variable is a global variable that is only visible from its local lexical scope.  For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   static counter = -1;&lt;br /&gt;
&lt;br /&gt;
   counter += inc;&lt;br /&gt;
&lt;br /&gt;
   return counter;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; is technically a global variable -- it is initialized once to -1 and is never initialized again.  It does not exist on the stack.  That means each time &amp;lt;tt&amp;gt;MyFunction&amp;lt;/tt&amp;gt; runs, the &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; variable and its storage in memory is the same.&lt;br /&gt;
&lt;br /&gt;
Take this example:&lt;br /&gt;
&amp;lt;pawn&amp;gt;MyFunction(5);&lt;br /&gt;
MyFunction(6);&lt;br /&gt;
MyFunction(10);&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In this example, &amp;lt;tt&amp;gt;counter&amp;lt;/tt&amp;gt; will be &amp;lt;tt&amp;gt;-1 + 5 + 6 + 10&amp;lt;/tt&amp;gt;, or &amp;lt;tt&amp;gt;20&amp;lt;/tt&amp;gt;, because it persists beyond the frame of the function.  Note this may pose problems for recursive functions: if your function may be recursive, then &amp;lt;tt&amp;gt;static&amp;lt;/tt&amp;gt; is usually not a good idea unless your code is re-entrant.  &lt;br /&gt;
&lt;br /&gt;
The benefit of a local static variable is that you don't have to clutter your script with global variables.  As long as the variable doesn't need to be read by another function, you can squirrel it inside the function and its persistence will be guaranteed.&lt;br /&gt;
&lt;br /&gt;
Note that statics can exist in any local scope:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pawn&amp;gt;&lt;br /&gt;
MyFunction(inc)&lt;br /&gt;
{&lt;br /&gt;
   if (inc &amp;gt; 0)&lt;br /&gt;
   {&lt;br /&gt;
      static counter;&lt;br /&gt;
      return (counter += inc);&lt;br /&gt;
   }&lt;br /&gt;
   return -1;&lt;br /&gt;
}&amp;lt;/pawn&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Ru:SourceMod Scripting]]&lt;/div&gt;</summary>
		<author><name>Frenzzy</name></author>
		
	</entry>
</feed>