ИЛИ if(Left (!Left && Right))
НЕ ИЛИ ИЛИ if(!((Left && !Right)
- Исправлены все недочёты, которые успел заметить
- Переписал создание домов (криво создавались)
- Исправил недоработку с прорисовкой объектов
- Переписал donate
- Добавил Perfomance для личного т.с
- Добавил финансовую статистику для бизнесов/АЗС
- В систему семей добавил банк
- Добавил в семью заместителя (возможность назначать/снимать)
- Добавил систему багажника для личного т.с /baggage (реализация так себе конечно)
- В донат добавил возможность покупки попугая (можно придумать ему имя, улучшить, чем больше уровень улучшений - тем чаще повторяет /toy)
- В донате можно купить любой номерной знак
- Добавил команду /park - возможность самостоятельно припарковать авто в радиусе м от дома
- Переделал оформление немного
- Новые команды для админов (/msgr - сообщение в радиусе для игроков, /gfinka /bfinka - просмотр финки бизнеса/АЗС, /crashed - крашнуть игрока)
- Если у админа различаются последний и текущий IP-адрес его права должен подтвердить старший администратор (/acceptadmin)
- Добавил возможность изменять освещение в доме
- Добавил новые интерьеры для домов (маппинг с паблика)
- В мэрии можно посмотреть статистику игроков (самые богатые, старые, донатеры и т.д.)
- Теперь создать семью можно в семейном центре (5 уровень и $)
- Теперь, чтобы вступить в организацию или стать лидером - нужно пройти простой RP-тест (/menu)
- Убрал поочерёдную систему репорта (теперь стандартная)
- Добавил новые функции для VIP (в планах полностью её переписать)
- В /menu теперь доступен ежедневный подарок (может выпасть что угодно, доступно с 3 уровня)
- В /apanel теперь можно посмотреть список игроков онлайн с мутом, в тюрьме
- В /apanel для старшей администрации теперь доступна функция отключать/включать доступ к казино
- Поменял интерьер в казино (переделать /dice и сделать крупье)
- Добавил команду /boostinfo (посмотреть текущие акции для игроков)
- Теперь при наличии более $ на руках у игрока появляется мешок с деньгами (можно убрать в настройках)
- В настройках можно изменить стиль игрового чата (как на Advance RP)
- Добавил /lmenu (возможность зареспавнить незанятый транспорт организации, посмотреть список игроков во фракции, управление банком организации)
- В /lmenu для президента добавлена возможность просмотра казны и управления налогом
- Для лидеров банд добавлена команда /fpay - выдать премию членам организации в сети
- Добавил команду /vacancy (можно посмотреть доступные вакансии, а лидерам организаций добавить их)
- Сделал систему репутации для администраторов (после ответа на репорт игрок может оценить ответ)
- Добавлена справочная книжка (/dir - посмотреть заместителей и т.д.)
- Полностью переписана система обработки объявлений для СМИ
- Система погоды (каждые 20 минут меняется погода в штате)
- В /apanel основателю можно изменять название сервера
- При создании дома можно указать наличие гаража (0 - нет, 1 - да), добавлена система гаражей, он есть не у всех домов. Если в доме имеется гараж, то нельзя использовать /park
- Исправил недочёты с попугаем (сохранение)
- Добавил в /apanel телепорт в goalma.org (также доступна /az [id игрока] для телепорта в зону)
- Добавил новый интерьер для армий
- В /donate добавлена возможность обнулить трудовую книжку
- Теперь, чтобы убрать временный скин, можно ввести команду /end
- МВД и мафиям сделана команда /object (заграждения, объекты), также при установке пишет ID игрока, который его установил (/break убрана)
- Добавлена система аксессуаров (можно приобрести пока что только в донате или выдать от имени администратора или получить в семейном центре)
- Добавлена команда /vad. С помощью неё Вы сможете выделить своё объявление как VIP (стоимость услуги $)
- Для бандитов добавил возможность грабить транспорт в гетто (/robcar, copy Advance). Владельцы ограбленного авто должны
будут оплатить его ремонт в полицейском участке.
- Помимо VIP сделан статус PREMIUM, у которого есть свои привилегии
- Добавлены печенья (их можно обменять на что-то ценное)
- Сотрудникам СМИ добавлена команда /skin > продать костюм игроку
- Добавлен новый класс дома - Luxury, у этого класса желтый пикап (отличие от остальных)
- Теперь вместо чекпоинтов у домов - пикапы
- В семья добавлены ранги. Всего 5 рангов, названия может менять только владелец семьи. Теперь игрок с 4 рангом в семье может принимать и выгонять из семьи
- Добавлен семейный центр в ЛС (у автошколы). Там можно создать семью, посмотреть рейтинг семей, обменять печенье на призы
- Переписаны банки. Теперь есть Центральный банк в ЛС и его филиалы в СФ и ЛВ, в ЦБ можно создавать счета и т.д., а в филиалах
доступны депозитные счета. Процентная ставка зависит от статуса (обычный - %, ВИП - %, ПРЕМИУМ - %), пополнять и снимать
средства с депозитного счёта можно раз в сутки
- В банки добавлены говорящие актеры (анимка и текст над головой)
- Переписана команда /tp
- Сделал систему репутации для администраторов (после ответа на репорт, игрок может оценить ответ)
- Сделал тип бизнеса - бар (свой интерьер добавил)
- Сделан функционал обмена печенья на ценные призы в "Семейном центре". Вы можете обменять 20 шт. печенья на рандомный приз.
Печенье выдаётся каждый час по 1 шт. (вип игрокам - 3 шт., премиум игрокам - 5 шт.)
P.S В скором времени планирую добавить квесты, за выполнение тоже будут выдаваться печенья
- Администраторам добавлена команда /getowner (посмотреть владельца т/с)
- Управление семьей перенесено в /mn > управление аккаунтом > управление семьей
- Владелец семьи теперь может привязать дом к семье, игроки смогут в нем спавниться, правда для этого класс дома
должен быть как минимум "Элитный".
- Покинуть и удалить семью теперь можно только в семейном центре
- В 3D тексте у дома пишет название семьи, которой принадлежит дом
- Теперь в семейном центре можно изменить название семьи
- Когда разгружаешь ящики с патронами или медикаментами на склад организации (об этом пишет в чат фракции)
- Исправлен баг с отображением времени при bizwar у мафий
- Теперь античит не срабатывает на SpeedHack, если Вы используете Perfomance Tuning
- При смене ника в таблице MySQL теперь изменяется ник зама и лидера (если игрок таковым является)
- В /time пишет время заключения и затычки (если они есть)
- В больницы добавлены регистратуры, там можно пройти курс платного лечения (мгновенно вылечиться), если на сервере отсутсвуют
goalma.orgики учереждения, в котором находится игрок (если работники есть - вылечиться будет нельзя)
- Исправлен баг с пикапом на сдачу экзамена в АШ
- В автошколу добавлен вертолёт, а также возможность сдать экзамен на воздушный транспорт (сделана практическая сдача)
- В /lmenu добавлена возможность создавать объявления для сотрудников (они смогут его посмотреть с помощью команды /advert)
- Добавлен PREMIUM авторынок в СФ для обладателей PREMIUM аккаунта. Там можно приобрести транспорт, который не купишь в обычном автосалоне.
На авторынке доступно ограниченное количество автомобилей (админы могут добавить командой /addcar [модель машины] [цена])
- Добавлены ключи от камеры в КПЗ, при наличии ключа Вы сможете выйти из тюрьмы с помощью команды /unjail. Ключи можно получить через донат
или обменяв на печенье в семейном центре.
- В семейном центре при обмене печенья теперь можно получить PREMIUM (шанс очень маленький, но всё же)
- Исправил команду /respv (выдавало в лог ошибку)
- Исправлен баг со сдачей прав
- Исправлен баг с выдачей аксессуаров командой /giveaccs (путались слоты)
- При регистрации можно указать национальность персонажа (в дальнейшем будет функционал для этого)
- В порту СФ добавлен продавец семян Ричи. Он появляется в , , и по серверному времени.
У него бандиты могут приобрести семена, с помощью которых можно выращивать куст конопли (/plant), после выращивания куста
получаются наркотики. Их бандиты могут продать в притон (в гетто).
- Переписан притон в гетто. Теперь лидеру банды, которая контролирует территорию с притоном доступна команда /hangout.
Там можно изменить цену на продажу и покупку наркотиков, а также пополнить баланс или снять с баланса притона денежные средства
- Исправлен баг с аксессуарами (путались слоты)
- Убрана команда /selldrugs (за ненадобностью)
- Исправлен баг с /alogin, когда аккаунт только что зарегистрирован
- Теперь проверка на совпадение IP действует на всех администраторов кроме 6 уровня
- В /report теперь нельзя подать жалобу на самого себя
- Добавлена система достижений. На данный момент сделано 5 достижений, за выполнение которых игроку выдаётся уникальный аксессуар,
который нигде нельзя приобрести. Информацию о достижениях можно посмтреть в меню /mn > 10 пункт
- Переписана система промокодов. Отныне существует 3 типа промокодов - для гос, банд и ловцов имущества.
Администраторы могут создавать и удалять промокоды командами /addpromo, /dellpromo. Также можно смотреть статистику промокодов /promolist.
Промокод устанавливается на определенного игрока (держатель промо), он может просматривать подробную статистику промокода (кол-во активаций, дата создания)
Игрок, который активировал промокод, может просматривать информацию о бонусах, которые ему достанутся по достижении определенного уровня.
- Игрокам от 3 уровня добавлена команда /pame - установить описание персонажа (сохраняется при перезаходе)
- Администраторам добавлена команда /apame - удалить описание персонажа у игрока
- Теперь при бане/варне слетает админка
- Переписано обнуление игроков при подключении/отключении с сервера
- Теперь в 24/7 можно купить шашку Taxi и работать таксистом на личном авто, при этом трудоустраиваться не нужно (/taxi)
- В /lmenu лидер теперь может изменять цвет организации в формате hex-color
- Команда /logs теперь работает исправно (просмотр последних 25 действий администратора к игроку)
- Теперь в личном меню игрок может посмотреть 25 последних наказаний на своём аккаунте
- Теперь каждый PayDay обновляется рейтинг семей (рейтинг даётся семье если игрок лидер, имеет VIP или PREMIUM)
- Администраторам 6 уровня добавлена команда /bizlock (заблокировать доступ к бизнесу)
- В /apanel для 5 уровней добавлен топ донатеров
- Добавлена команда /jp (получить jetpack) для администраторов 3 уровня
- В /apanel возвращены настройки администратора (информация о подключении игроков, просмотр килллиста)
- Добавлена реклама на сервер с полезной информацией
- Добавлена система подсказок (/hint). Теперь с получением нового уровня, игроку будет доступна подсказка об игре на сервере (пока сделал для 3 уровней)
- Добавлен TextDraw телефона (показывается дата, можно позвонить, посмотреть контакты, отправить смс)
- Убраны команды /contacts, /call - вместо них добавлена /phone (меню телефона)
- Исправлена смена имени за донат и /okay
- Теперь корректно списывается донат (сохранение)
- Исправлен баг, когда по окончанию войны за территорию у бандитов не пропадали 3D текста над головой
- Переписаны гангзоны (теперь ровные квадратики, всего территорий)
- Добавлена админ комната (телепортироваться можно через /apanel)
- Добавлена команда /az, для того чтобы телепортировать игрока на собеседование в goalma.orgу
- В админ комнату добавлена общая статистика сервера
Нажмите для раскрытия
If – это условный оператор, в скобках перед оператором пишется условие. После скобок точка с запятой
не ставится. В фигурных скобках пишется код который выполнится, если условие истинно. Если условие ложно,
код не выполнится. Else – это также условный оператор, но он выполняет свои функции, только в том случае,
если условие в if ложно. То есть, оператор if можно назвать как оператор «если», а еlse как оператор «иначе».
Давайте поставим простейшее условие. У нас есть две заранее проинициализированных переменных:
1 new a = 5;
2 new b = 25;
Поставим такое условие, если a < b, в консоль сервера выведется текст: «a меньше b». Если же значение
переменной a не меньше b, в консоль сервера выведется текст: «a больше b».
1 if(a < b)
2 {
3 print(“a меньше b”);
4 }
5 else
6 {
7 print(“a больше b”);
8 }
В данном примере выполнится кол в if, так как 5 меньше Но что если a равно b. Тогда мы поступим
следующим образом: (между строкой) вставим, операторы else if и условие, в общем, так как показано на
примере ниже:
1 if(a < b)
2 {
3 print(“a меньше b”);
4 }
5 else if (a == b)
6 {
7 print(“a равно b”);
8 }
9 else
10 {
11 print(“a больше b”);
12 }
Для некоторых случаев совсем необязателен оператор else, например, в командах чата. Например,
случай такой, нам нужно, чтобы команда не выполнялась до тех пор, пока игрок не авторизуется на сервере.
Мы пишем условие внутри команды, при котором команда не выполнится, и ставим в конце кода return 1. В
приведенном ниже примере Return завершает работу функции OnPlayerCommandText и не дает ей
выполниться до конца. Под данным условием уже можно будет писать код команды.
1 ++a;
1 a++;
Когда мы прибавляем к значению переменной единицу при помощи инкремента, таким образом, мы
инкрементируем переменную. Когда мы отнимает от значения переменной единицу при помощи декремента,
таким образом, мы декрементируем переменную.
Разницу между префиксным или постфиксным инкрементом и декрементов вы увидите в следующем
примере, для этого в функции OnGameModeInit нужно добавить эти строчки и запустить сервер.
1 new a = 25;
2 printf(“%d”,a++);
В вышеуказанном примере показана работа постинкремента. Мы увидим число 25 а не 26, потому что
постинкремент сначала возвратит нам старое значение переменой до ее инкрементирования. Если мы
поставим вместо постинкремента – преинкремент, то мы увидим число Аналогично и с декрементом.
Урок №08 – Циклы while и do while
Цикл While и любой другой цикл, повторяет свою функцию бесконечно до тех пор, пока его условие
истинно. Если его условие будет ложно, цикл прекращает работу. Цикл выглядит следующим образом:
1 new a;
2 while(a <= 3)
3 {
4 a++;
5 print("Hello, World!");
6 }
Как это работает? Все очень просто. Цикл проверяет условие, если, а меньше или равно 5, он выполняет
свою функцию. В вышеуказанном примере так оно и есть, так как наша переменная была создана, но не
проинициализирована, то есть ей не задано значение и оно равно – 0. Инкрементируем переменную Post-
инкрементом. То есть сначала возвращается старое значение, а потом только оно увеличивается на единицу и
затем идет печать текста «Hello, World!» в консоль сервера функцией print. В итоге мы в консоли сервера
получим четыре раза текст «Hello, World!».
Перейдем к следующему циклу, do while. Если while сначала проверял условие, а затем выполнял свою
функцию, то do while делает все с точностью да наоборот. Сначала он выполняет свою функцию, а потом
проверяет условие.
Чтобы сделать из вышеуказанного цикла, цикл do while, достаточно верхнюю часть цикла вместе с
условием перенести под фигурные скобки и в конце после условия после закрывающей круглой скобки
поставить точку с запятой, а на то место, откуда вы вырезали while, поставить оператор do.
1 new a;
2 do
3 {
4 a++;
5 print("Hello, World!");
6 }
7 while(a <= 3);
Тут принцип работы аналогичен, и в результате мы получаем то же самое, что и при простом цикле while.
Урок №09 – Цикл for
Цикл For – это, по сути, упрощенный цикл While, поэтому я не буду долго заострять на этом внимание.
Сейчас вы убедитесь на примере из прошлого урока, который продемонстрирован ниже:
1 new a;
2 while(a <= 3)
3 {
4 a++;
5 print("Hello, World!");
6 }
Цикл for выполнять аналогичные функции, что и цикл while. Сейчас я покажу, как превратить данный цикл
в цикл for. Для этого, оператор while заменяем на for. Переменную a вместе с оператором new и точкой
запятой перемещаем перед условием в скобках, в конце условия также ставим точку с запятой. Берем
инкремент полностью, как мы брали переменную и перемещаем после условия. А все остальное остается на
месте, в результате мы получаем цикл For.
И на заметку, не рекомендуется скрипт перегружать циклами. И еще что особенно важно нежелательно
использовать конструкцию: «цикл в цикле» это дает сильную нагрузку на сервер.
Но тем не менее циклы очень полезны. Их очень удобно использовать для поиска по массивам, а также
для выполнения одной и той же операции для всех или определенных игроков одновременно.
Урок №10 – Операторы Break и Continue
Данные операторы используются в циклах: for, while, do-while. Оператор break завершает работу цикла,
а оператор continue, пропускает оставшееся действие цикла и повторяется снова. Рассмотрим два оператора в
действии. У нас есть цикл for из прошлого урока:
1 new a;
2 while(a <= 3)
3 {
4 a++;
5 print("Hello, World!");
6 }
Сделаем так, чтобы в консоль сервера вывелся текст «Hello World!» не 3, а 2 раза. Вспоминаем урок про
условные конструкции и создаем такое условие: если a равен 3, то завершаем работу цикла.
1 new a;
2 while(a <= 3)
3 {
4 if(a == 2)
5 {
6 break;
7 }
8 a++;
9 print("Hello, World!");
10 }
Если вместо оператора break подставить оператор continue результат получится тот же. Вы спросите, в
чем же тогда разница, если результат один и тот же. В этом цикле есть один подводный камень. Если вы
прочитаете последовательность действий цикла, то поймете в чем причина. А причина вот в чем:
Цикл проверяет последовательно условия, начиная с 0, так как переменная а – равна 0. В первом и во
втором случае, условия истинны, так как 0 и 1 меньше 3 и не равны 2. Соответственно в чат выводится 2 раза
текст «Hello, World». Что break, что continue они не дают до конца выполнить цикл, то есть все функции, что
находятся после самого оператора (инкремент и функцию print).
Для того, чтобы увидеть отличие этих двух операторов нужно инкремент переместить перед условием,
вот так:
1 new a;
2 while(a <= 3)
3 {
4 a++;
5 if(a == 2)
6 {
7 break;
8 }
9 print("Hello, World!");
10 }
В случае с оператором break, в консоль выведется текст «Hello, World!» всего один раз. Так как
пропускается одно условие из-за инкремента, где переменная «а» должна быть равна 0. В случае с оператором
continue текст выведется три раза, так как оператор пропускает под собой все оставшиеся функции цикла и
начинает следующий цикл.
Урок №11 – Форматирование строки c помощью printf и format
С помощью оператора format можно передать в строку значения переменных или функций, других
строк и просто текст, который нужно передать в строку. У функции если не считать, сколько всего будет
передано в строку, всего 4 аргумента. Первый аргумент, это имя строки, в которой сохранятся
форматированная строка. Второй аргумент длина этой строки, обычно вместо длины строки используют
функцию sizeof с именем строки в качестве аргумента этой функции. Затем третьим аргументом следует текст в
кавычках и управляющие символы. Управляющие символы приведены в таблице ниже:
%b Бинарный тип
%c Символьный тип
%d, %i Целочисленный тип
%f Число с плавающей точкой – вещественный тип
%s Строка
В строку можно передать неограниченное количество значений, сколько значений передается, столько
и управляющих символов в строке. Главное соблюдать типы передаваемых данных. При передачи целого числа
в строку, нужно использовать управляющий символ (%d) целочисленного типа, при передачи десятичного числа
(%f) управляющий символ вещественного типа, при передаче другой строки нужно использовать управляющий
символ - %s и так далее.
Привожу для следующего примера инициализированные строки и заранее одну пустую строку где будет
сохранен форматированный текст:
Принцип работы функции такой. Он берет значение из переменной Samp указанной в нижеприведенном
примере и подставляет вместо управляющего символа %s, получает текст «Hello, world!».
1 format(string,sizeof(string),”%s world!”,Samp);
Можно передать в строку сразу 2 или более значения. Для этого в 3-ем аргументе в кавычках ставим
управляющий символ в то место, куда нужно будет вставить значение. Затем в зависимости от того куда мы
поставили управляющий символ, в 4-ом аргументе через запятую указываем строку или переменную, из
которой будет браться значение. Главное соблюдать порядок. Первая переменная или строка в 4-ом аргументе
передается свое значение в 1-ый управляющий символ в 3-ем аргументе, вторая во второй, третья в третий, как
показано на примере ниже:
Можно не указывать ни строк, ни переменных, а текст, который нам нужно вставить, вот пример:
Все вышеуказанные примеры имеют одинаковый результат. Кроме всего вышеуказанного в строку
можно вставлять следующее символы, приведенные в таблице:
\b backspaсe
\f Form feed
\n переход на новую строку
\r возврат каретки
\t табуляция
\v вертикальная табуляция
\' одиночная кавычка
\" двойные кавычки
\? вопросительный знак
Функция printf аналогичная, она как функция format только без первого и второго аргумента, и
значительно проще, так как ей не нужно никаких строк. Она выводит форматированную строку в консоль. Вот
так выглядит функция, аналогичная функции на примере выше.
1 public OnPlayerConnect(playerid)
2 {
3 new plname[MAX_PLAYER_NAME];
4 new string[50];
5 GetPlayerName(playerid,plname,24);
6 format(string,sizeof(string),"*** %s зашел на сервер. (ID:%d)",plname,playerid);
7 SendClientMessageToAll(COLOR_GREEN,string);
8 return 1;
9 }
Для того чтобы вывести сообщение всем игрокам, существует функция SendClientMessageToAll. В
скобках функции два аргумента. Первый аргумент, цвет сообщения, куда мы подставляем HEX-код цвета либо
заменяем его константой для удобства, второй аргумент – текст, выводимый в чат всем игрокам.
Итак, для того чтобы вывести сообщение всем игрокам, для начала нам нужно 2 строки (одномерных
массива). MAX_PLAYER_NAME – это встроенная константа, она равна 24, то есть максимальной длине имени
игрока. Первая строка будет хранить имя игрока, вторая будет хранить отформатированный текст сообщения,
передаваемый игрокам. Функция GetPlayerName получает имя игрока, и как показано во 2 аргументе функции,
передает в переменную plname это имя.
Имя нам известно, ID игрока тоже, теперь пора приступить к форматированию строки. Пишем функцию
format и первым аргументом функции указываем переменную string, где будет храниться сообщение. Вторым
аргументом при помощи функции sizeof, передаем размер этой переменной. В третьем аргументе функции
пишем текст. Имя, это строка, для передачи в строку, нужен управляющий символ «строка» (%s), ID игрока, это
целое число, для передачи в строку, нужен управляющий символ целочисленного типа (%d).
Выше показан заведомо неправильный пример. Мы не можем передать ID игрока то есть целое число в
управляющий символ «строка», так как число это не текст (не строка). Имя игрока мы также не можем передать
в управляющий символ целочисленного типа, так как строка (или текст) это не число. При форматировании
строки соблюдайте типы передеваемых данных и управляющие символы для этих типов.
Урок №12 – Арифметические выражения в Pawn
Примеры, указанные в таблице выше четко отображают простейшие математические операции между
значениями двух переменных pawn и samp. Давайте рассмотрим данные примеры на переменных, которые
приведены ниже:
Переменная, которая должна присвоить себе результат арифметического выражения всегда должна
быть впереди выражения. С помощью скобок в арифметических выражениях можно задать
последовательность выполнения вычислений.
Как получилось 2? Все просто, складываем значения переменных, так как они в скобках и делим на 7. Мы
получаем приблизительно 4,2. Если умножим 4 на 7, получим 28, ближайшее к 30 число. Если отнимем 30 от 28,
получим тот самый остаток.
Решим еще одно выражение, пусть переменная pawn будет равна В итоге сумму переменных то есть
36 делим на 7 и получаем 5. Умножаем 5 на 7, получаем Отнимаем его из 36, в результате чего получаем тот
остаток 1.
Урок №13 – Оператор switch
Оператор switch – это оператор выбора. Он удобен в первую очередь тем, что может заменить много
условий if, которые проверяют значение одной переменной. Представим себе такой пример. У нас есть
целочисленная переменная pawn, значение которой нужно проверить. И в зависимости от того, какое значение
у данной переменной выполнить соответствующий код.
1 new pawn;
2 switch(samp)
3 {
4 case 0: //аналог условия if(samp == 0)
5 {
6 print(”Переменная samp = 0”);
7 }
8 case 1: //аналог условия if(samp == 1)
9 {
10 print(”Переменная samp = 1”);
11 }
12 }
Обратите внимание, если в фигурных скобках указано одно действие, его можно упростить так же как в
случае с обычной условной конструкцией.
Но, что если переменная не попадает ни под одно условие в операторе switch. Тогда можно
использовать default, он выполняется только в том случае, если switch не попадает ни в один из case.
1 new pawn;
2 switch(samp)
3 {
4 case 0: printf(”Переменная samp = 0”);
5 case 1: printf(”Переменная samp = 1” );
6 default: printf(”Переменная samp = %d” , samp);
7 }
То же самое можно сделать и с помощью обычной условной конструкции if, тогда код выглядел бы
следующим образом:
1 if(samp == 0)
2 {
3 printf(”Переменная samp = 0”); //все равно что case 0
4 }
5 else if(samp == 1)
6 {
7 printf(”Переменная samp = 1”); //все равно что case 1
8 }
9 else
10 {
11 printf(”Переменная samp = %d” , samp); //все равно что default
12 }
Этот способ удобнее и читабельнее чем много if конструкций идущих подряд. Еще одно отличие, что в
case можно указать диапазон значений куда проще, чем в обычной условной конструкции if.
Для закрепления знаний по данному урока продемонстрирую вам один из примеров использования
данного оператора в функции OnPlayerDisconnect. В данной функции параметр reason возвращает ID причины
отключения игрока от сервера. Благодаря этому параметру можно сделать вот такой код оповещения игроков
о уходе игрока с сервера с пояснением причины.
1 switch(reason)
2 {
3 case 0:
4 {
5 GetPlayerName(playerid,plname,24);
6 format(string,sizeof(string), "*** %s вылетел с сервера.(ID:%d)",plname,playerid);
7 SendClientMessageToAll(0xAAAA,string);
8 }
9 case 1:
10 {
11 GetPlayerName(playerid,plname,24);
12 format(string,sizeof(string), "*** %s покинул сервер.(ID:%d)",plname,playerid);
13 SendClientMessageToAll(0xAAAA,string);
14 }
15 case 2:
16 {
17 GetPlayerName(playerid,plname,24);
18 format(string,sizeof(string), "*** %s был кикнут.(ID:%d)",plname,playerid);
19 SendClientMessageToAll(0xAAAA,string);
20 }
21 }
1 stock GetName(playerid)
2 {
3 new nick[MAX_PLAYER_NAME];
4 GetPlayerName(playerid, nick, sizeof(nick));
5 return nick;
6 }
В этом случае функцию GetPlayerName можно просто убрать из switch, а вместо переменной plname
подставить вызов данной функции. Саму переменную plname также нужно удалить.
Урок №14 – Создание простейшей команды
Функция OnPlayerCommandText, выполняется, в том случае если игрок введет команду в чат. Первый
параметр функции, это ID игрока, который ввел команду, второй параметр, это строка, которая хранит
введённую игроком команду. Чтобы создать простейшую команду, нам нужно проверить правильно ли ввел ее
игрок. Для этого нам надо сравнить введенную игроком команду с ее оригиналом.
Для сравнивания строк существует функция strcmp.
strcmp – имеет четыре аргумента. Первый аргумент имя строки, которая будет сравниваться с другой
строкой, второй аргумент – имя строки, с которой будет сравниваться предыдущая строка. Третий аргумент
логический аргумент. Если указать true – то при сравнении строк регистр букв не учитывается, по умолчанию,
если даже его не указать регистр учитываться будет.
Хочу отметить, что если вы не указали третий аргумент, то и четвертый аргумент уже указать не
получится, поскольку пустой аргумент оставлять нельзя. Также если третий аргумент не обязательный для
указания, а четвёртый аргумент обязательный, то третий аргумент, так или иначе, придется указать, пропускать
аргументы нельзя. Так как у функции strcmp два последних аргумента не обязательны, их можно не указывать,
поскольку они последние. Сама функция возвращает 0 – если совпадение %, в противном случае возвратит 1.
Ну а дальше все зависит от вас. Если условие по сравнению команд выполняется, команда обязательно
должна возвратить true (return 1;), потому что функция OnPlayerCommandText всегда возвращает false. Если
функция возвратит false, в чат будет выведено сообщение «Неизвестная команда», а сама команда сработает.
Урок №15 – Перебор значений в массиве
Что если нужно узнать, если определенное число в массиве или нет. Но функции поиска по массиву в
Pawn нет. Что делать? Поможет только перебор значений. Для этого нам нужен сам массив и цикл for. Вы уже
знакомы с массивами и циклами из прошлых уроков. Сейчас я на простом примере покажу, как сделать перебор
значений в массиве. И при появлении совпадения, должен выполниться скрипт.
Допустим, у нас есть большой одномерный массив со всеми ID машин, т. е только легкового транспорта.
Но сначала нам нужна новая автовызываемая функция, допустим, она будет называться IsPlayerInBike. В
скобках пишем два параметра – playerid и vehicleid. Функция будет выглядеть следующим образом:
1 stock IsPlayerInBike(playerid,vehicleid)
2 {
3 return 0;
4 }
1 stock IsPlayerInBike(playerid,vehicleid)
2 {
3 new IsBikeA[10] = {,,,,,,,,,};
4 return 0;
5 }
Теперь нам нужно присвоить второму аргументу нашей функции vehicleid - ID транспорта, в котором
сидит игрок. Чтобы узнать ID машины, существует функция GetPlayerVehicleID, которая возвращает ID
транспорта, в котором сидит игрок. Для этого мы присвоим аргументу значение, которое возвратит нам
вышеуказанная функция. Делаем это следующим образом, под массивом мы добавляем следующую строку:
1 vehicleid = GetPlayerVehicleID(playerid);
Дальше нам нужно проверить сидит ли игрок в машине с указанным ID. Функция IsPlayerInVehicle,
проверяет: сидит ли игрок в транспорте с указанным во 2 аргументе функции ID транспорта. На следующей
строчке пишем следующую условную конструкцию;
1 if(IsPlayerInVehicle(playerid,vehicleid))
2 {
3
4 }
В теле этой условной конструкции будет располагаться цикл, который будет искать требуемое значение
в массиве. Условие цикла должно быть следующее, если I < Переменная I у нас, это переменная счетчик, как
в любом цикле. То есть мы должны выполнить цикл 10 раз, так как в массиве у нас всего 10 ячеек или ID 10
мотоциклов.
Если совпадение найдено, функция должна вернуть true, если нет false. Под циклом обязательно должен
быть return 0, так как если совпадений не найдется, функция возвратит false.
Урок №16 – Расстановка транспорта
Чтобы проверить игрока в зоне, нам нужно написать в любом месте скрипта такую функцию:
1 if(IsPlayerInArea(playerid,,,,))
1 if(IsPlayerInArea(playerid,Xmin,Ymin,Xmax,Ymax))
Итак, встаем в левый нижний угол создаваемой вами зоны, получаем координаты командой save. Далее
встаем в правый верхний угол и снова получаем координаты. Допустим, мы уже получили вот такие
координаты:
1 AddPlayerClass(0,,,,,0,0,0,0,0,0);
2 AddPlayerClass(0,,,,,0,0,0,0,0,0);
Нужные нам координаты, я выделил цветом, т.е. это все координаты X и Y. Берем из этих координат
минимальную X-координату - Ставим ее первой в скобках, затем через запятую минимальную Y-
координату - Дальше то же самое, но уже максимальные координаты. Должно получиться так:
1 if(IsPlayerInArea(playerid,,, ,))
Урок №18 – Проверка игрока в кубе
Чтобы проверить игрока в кубе, нам нужно написать в любом месте скрипта такую функцию:
Эту проверку можно поместить, например, внутри команды. Теперь о том, как правильно получить все 4
координаты, указанные в скобках функции. Синтаксис условия такой:
1 if(IsPlayerInCube (playerid,Xmin,Ymin,Zmin,Xmax,Ymax,Zmax))
Итак, встаем в левый нижний угол создаваемой вами зоны, получаем координаты командой save. Далее
встаем в правый верхний угол и снова получаем координаты. Допустим, мы уже получили вот такие
координаты:
1 AddPlayerClass(0,,,,,0,0,0,0,0,0);
2 AddPlayerClass(0,,,,,0,0,0,0,0,0);
Нужные нам координаты, я выделил цветом, т.е. это все координаты X и Y. Берем из этих координат
минимальную X-координату - Ставим ее первой в скобках, затем через запятую минимальную Y-
координату - Дальше то же самое, но уже максимальные координаты. Должно получиться так:
Чтобы проверить игрока в радиусе, нам нужно написать в любом месте скрипта такую функцию:
В отличие от проверки в зоне или кубе тут достаточно получить 1 раз координаты и вручную
вписать радиус. Написав автовызываемую функцию PlayerToPoint, мы можем ставить такие условия:
Обычно, чтобы не запоминать цифры и не писать длинное название стилей диалогов, я заменяю их
такими константами:
Для написания основного текста диалогового окна вы можете использовать нижеприведенную таблицу:
\b backspaсe
\f Form feed
\n переход на новую строку
\r возврат каретки
\t табуляция
\v вертикальная табуляция
\' одиночная кавычка
\" двойные кавычки
\? вопросительный знак
Затем с помощью функции ShowPlayerDialog мы вызовем данное диалоговое окно. Так как вызывать
меню мы будем с помощью команды, то и пишем данную функцию, приведенную ниже внутри нее.
Цифра 0 – это идентификатор (ID) диалога, у каждого диалога свой ID. После идентификатора пишем
название стиля диалога, но я заменил его константой, поэтому я написал DSM (DIALOG_STYLE_MSGBOX). После
стиля пишем название диалога. Далее пишем текст диалога и название первой и второй кнопки.
В общем, код будет выглядеть следующим образом:
1 if (strcmp("/test", cmdtext, true, 10) == 0)
2 {
3 ShowPlayerDialog(playerid,0,DSM,"Подтверждение", "Вы точно хотите выполнить команду","Да","Нет");
4 return 1;
5 }
Но данное диалоговое окно работать не будет, если мы не напишем для него функцию. Допустим, наша
команда выдаст в чат всю информацию об игроке, т.е. при нажатии кнопки «Да» все так и будет, но при нажатии
кнопки «Нет», мы выдадим сообщение красным цветом о том, что данная команда не была выполнена.
Писать функцию диалогового окна мы будем в автовызываемой функции OnDialogResponse. Сначала
внутри функции мы напишем условную конструкцию, которая будет проверять, что данное диалоговое окно
было вызвано. Код условия такой:
Условие проверяет: было ли вызвано диалоговое окно с ID = 0. Внутрь этой условной конструкции
добавляем еще одно условие:
Условие проверяет, была ли нажата первая кнопка, если нажата вторая кнопка, то выполняется код
после else. Внутри этой условной конструкции для первой кнопки мы пишем следующий код.
1 if(response)
2 {
3 new string[]; //Переменная с основным текстом диалога
4 new plname[MAX_PLAYER_NAME]; //Переменная с именем игрока
5 new money; //Переменные для хранения кол-ва наличных денег игрока
6 new Float: health, Float: armor; //Переменные для хранения кол-ва здоровья и брони игрока
7 GetPlayerName(playerid,plname,MAX_PLAYER_NAME); //Записываем имя игрока в переменную plname
8 money = GetPlayerMoney(playerid); //Записываем деньги игрока в переменную money и т.д.
9 GetPlayerHealth(playerid,health);
10 GetPlayerArmour(playerid,armor);
12 format(string,sizeof(string),”Игрок: %s(ID:%d). Деньги: %d $.\n Здоровье: %.2f\n Броня: %.2f”,
plname,playerid,money,health,armor);
13 ShowPlayerDialog(playerid,1,DSM,"Информация об игроке",string,"ОК","");
14 }else{}
Сначала мы создаем все необходимые переменные, а потом получаем данные и сразу же их записываем
их во всех переменные. Обратите внимание на функцию GetPlayerMoney, в скобках она имеет всего один
аргумент (playerid), в отличие от других, и она возвращает количество денег игрока. Поэтому мы присваиваем
переменной money, эту функцию, которая возвратит значение, которое и будет значением этой переменной.
Еще обратите внимание на %.2f, я мог бы использовать просто %f, как показано в таблице. Точка и цифра
означает, сколько чисел должно быть после запятой у десятичного числа. Дальше мы форматируем сообщение,
после чего вызываем новое диалоговое окно с новым ID. Обратите внимание, что имя второй кнопки не
указано, в таком случае, эта кнопка просто будет отсутствовать в диалоге. А вместо основного текста мы
подставляем переменную string в которой уже есть готовое отформатированное сообщение.
Второе диалоговое окно будет выглядеть следующим образом:
Вернемся к условию, если будет нажата вторая кнопка в первом диалоге, тут все просто без объяснений
в else пишем:
1 SendClientMessage(playerid,COLOR_RED,"Команда отменена");
Вот в принципе и все, В следующем уроке мы рассмотрим другой стиль диалога. Переходим к
следующему уроку.
Урок №21 – Создание простого диалога с полем ввода
Данную строку я думаю, вы уже догадались, что ее нужно вписать внутрь готовой команды. Я
все также использовал константу DSI из прошлого урока, чтобы не писать длинное название стиля
диалога, поэтому не забудьте ее добавить в ваш скрипт.
Приступим к написанию функции для этого диалога. Как и в прошлом уроке, внутрь функции
OnDialogResponse, пишем условную конструкцию проверки на вызов диалога с ID = 0. Внутрь этой
условной конструкции пишем еще одну, проверку на нажатие кнопки. Дальше внутри этой проверки
будет еще одна проверка на то, что поле ввода у нас содержит какие-либо символы. Ведь мы же не
можем отправить пустой текст. Условная конструкция будет такая:
1 if(!strlen(inputtext))
2 {
3
4 }
5 else
6 {
7
8 }
В общем, думаю, вам будет все понятно, посмотрев нижеприведенный готовый скрипт, но все
же я вам кратко его объясню на всякий случай. Сначала идет проверка на вызов диалогового окна с ID
= 0. Мы данное окно вызывали функцией ShowPlayerDailog(playerid,0…); - я специально выделил
цифру, это dialogid. После проверки, внутри идет еще одна проверка на нажатие кнопки. Если нажата
кнопка 1, т.е. кнопка «ОК», идет следующая проверка на то, что в поле ввода есть какой-либо текст.
Если он есть, функция SendClientMessage отправляет в чат значение аргумента inputtext, т.е то, что
игрок введет в поле ввода диалогового окна. Если игрок не введет в поле ввода ничего, функция
SendClientMessage отправит в чат сообщение с ошибкой, о том, что текст сообщения не был введен в
поле ввода.
Перед тем как написать функцию для этого диалогового окна, давайте посмотрим на
следующую конструкцию приведенную ниже.
Вот так должен выглядеть код для данного стиля диалога. Тут мы проверяем значение listitem,
т.е. пункта списка которого мы выберем в диалоге. listitem = 1 – это кольт, значит, в условную
конструкцию listitem == 1 мы должны вписать функцию GivePlayerWeapon, чтобы дать оружие игроку.
1 if(listitem == 1) //Если был выбран 1 пункт списка
2 {
3 GivePlayerWeapon(playerid,22,); //Дать игроку кольт и патронов
4 }
То же самое делаем и для остальных listitem. Вписываем ту же строчку, только вместо 22,
пишем следующее: 23 – для кольта с глушителем, 24 – для пустынного орла (эти цифры, это ID модели
этого оружия). ID модели смотрите на странице «ID оружия».
Вообще, приведенный выше пример, очень схож с оператором switch, т.к. мы проверяем
значение одного аргумента и в зависимости от этого значения выполняем действие. Тоесть, это все
можно заменить на оператор switch, таким образом:
В этом уроке я научу вас создавать простые двери, открываемые по команде. Таким же
образом вы сможете потом ставить ворота и шлагбаумы. И начну я с фильтр скрипта Ingame Object
Editor. (данный скрипт прилагается к учебнику). Почему именно он, когда предлагают много раз MTA
Map Editor. Во-первых, это как один из простых способов расставить небольшое количество объектов,
если ставить много объектов, на это уйдет больше времени, чем в MTA Map Editor. Во-вторых, это
тоже было бы полезно знать. В-третьих, не нужно конвертировать код из map в pwn, все объекты
будут в вашем моде вместе с этим фильтр скриптом. Доступ к его опциям имеет только RCON
администратор, поэтому вам необходимо будет войти на сервер как RCON администратор.
Начнем с создания двери. Войдите на сервер как RCON администратор. Итак, вот место куда
мы, например, хотим поставить дверь.
1 ,,,,,,,1
1 ,,,,,,,1
/o_mode r_z – позволяет нам вращать объект таким образом, чтобы дверь открывалась и
закрывалась. Есть также r_xy – с помощью, которой уже вращаем дверь в другом направлении.
Запомните m_z и m_xy – это перемещение по осям: z и xy, а r_z и r_xy – это вращение по тем же
осям.
Итак, мы получили координаты закрытой и открытой двери. Теперь мы можем удалить этот
объект, т.к. у нас есть его координаты. Удаляем его командой /odel [имя объекта] в данном случае
имя объекта – door, значит, пишем /odel door. Удаляем мы его для того, чтобы у нас не получилось 2
копии двери, т.к. одну дверь мы вставим в мод.
Прежде чем приступить к делу объясню ниже приведенные цифры. Первая цифра означает ID
модели, следующие 3 цифры это координаты положения объекта, далее идут 3 цифры это координаты
вращения объекта, последняя цифра это видимость объекта.
1 ,,,,,,,1
1 cpd = CreateObject(,,,,,,,);
Видимость мы ставим , иначе вы будете видеть дверь, только подойдя к ней вплотную.
Затем пишем две команды, одну для открытия двери, другую для закрытия:
В этом уроке я научу вас записывать в файл данные стандартными средствами Pawn, т.е. без
использования посторонних инклудов. Итак, приступим.
Сначала мы рассмотрим запись в файл. Нам нужно вручную создать новый файл в папке
scriptfiles. Создадим файл goalma.org Дальше переходим к написанию скрипта, создаем переменную
для хранения имени игрока и дальше открываем файл, как это показано в скрипте ниже:
1 new plname[24];
2 File:nFile = fopen(“goalma.org”,io_append); //Открывает файл для добавления в него записи
nFile – это как идентификатор файла, название его может быть любое, я выбрал nFile.
fopen – открывает файл.
io_append – это метод открытия файла, все методы приведены в таблице ниже:
Давайте сделаем так, чтобы при подключении игрока, его имя записывалось в файл.
1 public OnPlayerConnect(playerid)
2 {
3 new plname[24];
4 GetPlayerName(playerid,plname,MAX_PLAYER_NAME); //Получаем имя и записываем в plname
5 File:nFile = fopen(“goalma.org”,io_append); //Открывает файл для добавления в него записи
6 fwrite(nFile, plname); //Записываем имя игрока в файл
7 fclose(nFile); //Закрываем файл
8 }
Но у скрипта есть большой недостаток, он записывает имена в строчку, что весьма неудобно.
Давайте сделаем так, чтобы имена игроков были в столбик. Для этого мы создадим переменную для
хранения отформатированной строки (string).
1 public OnPlayerConnect(playerid)
2 {
3 new plname[24], string[24];
4 GetPlayerName(playerid,plname,MAX_PLAYER_NAME);
5 format(string,sizeof(string),”%s\r\n”,plname);
6 File:nFile = fopen(“goalma.org”,io_append); //Открывает файл для добавления в него записи
7 fwrite(nFile, string); //Записываем имя игрока в файл
8 fclose(nFile); //Закрываем файл
9 }
В этом уроке я расскажу, как научится работать с include – mxINI. На момент написания
этого урока последняя актуальная версия инклуда Прежде чем приступить к изучению инклуда,
рекомендую его скачать. На основе этого инклуда в основном делают регистрацию на сервере. В
этом уроке я не буду показывать вам, как написать простейшую регистрацию на сервере, а всего
лишь объясню, как с помощью mxINI происходит запись и чтение из файла. Думаю, выяснив, как
работает данный инклуд, вы сами сможете написать простую регистрацию, возможно даже на
диалогах, так как урок с диалогами вы уже проходили.
Файл goalma.org нужно скопировать в папку include в директории с редактором Pawno. В
начале вашего скрипта обязательно нужно объявить этот инклуд, также как объявляется инклуд
a_samp.
Итак, приступим к разбору основных функций mxINI:
1 ini_setString(ID файла, "имя ключа", "текст"); // Эта функция записывает текст в ключ.
2 ini_setInteger(ID файла, "имя ключа", ); // Эта функция записывает целое число в ключ.
3 ini_setFloat(ID файла, "имя ключа", ); // Эта функция записывает десятичное число в ключ.
1 ini_getString(ID файла, "имя ключа", <имя переменной>); // Эта функция записывает текст в переменную из
файла.
2 ini_getInteger(ID файла, "имя ключа", <имя переменной>); // Эта функция записывает целое число в
переменную из файла.
3 ini_getFloat(ID файла, "имя ключа", <имя переменной>); // Эта функция записывает десятичное число в
переменную из файла.
Запись в файл
Давайте на простом примере с помощью команды, запишем данные игрока: имя, деньги и
количество здоровья. Сначала мы создаем 2 переменные, где у нас будут храниться имя игрока и
отформатированное сообщение.
1 if(iniFile < 0)
2 iniFile = ini_openFile(string);
Вот так производится запись данных в файл. Запись в файле будет выглядеть примерно следующим
образом:
1 Name = Player
2 Money =
3 Health =
Чтение из файла
Чтение из файла ничем не сложнее записи, все аналогично. Только тут не нужно проверок, условий:
if(iniFile < 0), и в переменной iniFile мы не создаем, а уже открываем созданный нами файл. Весь код будет
выглядеть следующим образом:
Во многих скриптах, очень часто используется переменная для хранения имени игрока. Она очень
много раз создается в различных частях кода. Но можно избежать создания такого большого количества
переменных и обойтись одной. Так как в этом случае очень часто используется функция GetPlayerName,
логично создать отдельную функцию, которая будет вызываться в разных частях кода. Поскольку return
может возвращать только целое число или строку, можно написать вот такую простейшую функцию.
1 stock PlayerName(playerid)
2 {
3 new PlayerName[MAX_PLAYER_NAME];
4 GetPlayerName(playerid,PlayerName,sizeof(PlayerName));
5 return PlayerName;
6 }
Теперь при необходимости узнать имя игрока в определенной части кода, нужно просто вызвать
данную функцию. Вот так бы выглядел код с выделением переменной под имя игрока.
1 new string[60];
2 format(string,sizeof(string),”Добро пожаловать к нам на сервер: %s”,PlayerName(playerid));
3 SendClientMessage(playerid,COLOR_YELLOW,string);
Непонятным остается только одно. Почему разработчики SAMP не решили переделать функцию
GetPlayerName подобным образом.
Урок №27 – Проверка расстояния между игроками
В этом уроке я научу вас, как делается проверка на расстояние между игроками. Допустим, у
нас есть команда передачи денег и нам нужно, чтобы игроки были близко друг к другу, чтобы они
могли передавать деньги между собой. В этом уроке я покажу, как делается всего лишь проверка.
Итак, приступаем:
Для организации проверки в начало скрипта мы добавляем следующую строку, которая
объявит новую автовызываемую функцию, которая будет отвечать за проверку на расстояние
между игроками.
Ну, думаю из кода понятно, что сначала мы проверяем, подключены ли к серверу оба
игроками. Затем мы получаем координаты обоих игроков функцией GetPlayerPos. Далее мы
вычитаем X-координату игрока передающего деньги, от X-координаты получающего деньги и
записываем результат в переменную tempposx, то же самое делаем и с остальными координатами.
Ну а дальше простая математическая проверка, думаю, вам там будет все понятно. Теперь,
когда у вас уже готов этот скрипт, можно ставить такие условия:
1 new string[];
2 new cmd[];
3 new playermoney;
4 new sendername[MAX_PLAYER_NAME];
5 new giveplayer[MAX_PLAYER_NAME];
6 new giveplayerid, moneys, idx;
7 cmd = strtok(cmdtext, idx);
Переменная string у нас будет хранить текст сообщения о передачи денег между игроками,
cmd будет хранить весь текст команды. Sendername будет хранить имя игрока передающего
деньги, giveplayer – имя получающего деньги. Переменная giveplayerid будет хранить ID игрока
получающего деньги, money – будет хранить количество передаваемых денег, а idx будет хранить
параметры команды. Теперь собственно приступаем к разбору самой команды. После переменных
в переменной cmd определяем пробел между командой и параметром (7 строка). Все начинается с
простейшей команды:
1 new tmp[];
2 tmp = strtok(cmdtext, idx);
3 if(!strlen(tmp))
4 {
5 SendClientMessage(playerid, COLOR_WHITE, "Введите: /givemoney [id игрока] [сумма]");
6 return 1;
7 }
8 giveplayerid = strval(tmp);
9 tmp = strtok(cmdtext, idx);
10 if(!strlen(tmp))
11 {
12 SendClientMessage(playerid, COLOR_WHITE, " Введите: /givemoney [id игрока] [сумма]");
13 return 1;
14 }
15 moneys = strval(tmp);
Объясняю. Создаем переменную tmp, которая будет хранить параметры команды, это
текст, который будет после пробела. Определяем функцией strtok, проблем между командой и
параметром (2 строчка). Ставим условие, если параметр не введен, отправляем в чат сообщение.
Присваиваем переменной giveplayerid, значение первого параметра, которой мы ввели (8
строчка). Снова определяем пробел, но уже между двумя параметрами. Поскольку в команде
вводится 2 параметра: ID игрока и сумма денег. Также проверяем, что параметр введен и
присваиваем переменной money, значение 2 параметра, которое мы ввели в команде.
Вот пример: ввели вы команду: /givemoney 1 Переменная giveplayerid получает
значение 1 параметра, то есть будет равно 1, переменная money получает значение 2 параметра и
будет равна Итак, идем дальше:
Дальше мы пишем проверку, подключен ли игрок, получающий деньги к серверу.
1 if (IsPlayerConnected(giveplayerid))
2 {
3 GetPlayerName(giveplayerid, giveplayer, sizeof(giveplayer));
4 GetPlayerName(playerid, sendername, sizeof(sendername));
5 playermoney = GetPlayerMoney(playerid);
Читаю условие: если количество денег, которые игрок хочет передать другому игроку
(moneys) больше 0 и количество денег, которое у него есть (playermoney) больше или равно тому
количеству, которое он хочет передать (moneys), то мы передаем деньги игроку функцией
GivePlayerMoney. Отнимаем у игрока передающего количество передаваемых денег, и даем их
игроку получающему деньги.
Ну и не забудьте для проверки на подключение игрока получающего деньги поставить else,
действие, если игрок не подключен к серверу.
1 }
2 else
3 {
4 format(string, sizeof(string), "%d не подключен к серверу.", giveplayerid);
5 SendClientMessage(playerid, COLOR_YELLOW, string);
6 }
Ну и напоследок. Если все же при компиляции скрипта pawno будет ругаться на strtok, то
добавьте в скрипт эту функцию:
Return всегда возвращает чего-либо. В данном уроке я научу вас использовать его. При построении
сложных команд, будет очень важно знать этот урок. Допустим, у нас есть одно условие внутри команды из
функции OnPlayerCommandText:
1 if(pLogged[playerid] == false)
2 {
3 SendClientMessage(playerid, COLOR_RED, "Вы не авторизованы на сервере");
4 }
5 else
6 {
7 //Выполнить код команды
8 }
С помощью return мы можем упростить это условие, отбросив оператор else. Для это убираем
оператор else и фигурные скобки, выравниваем код команды и получаем следующее:
1 if(pLogged[playerid] == false)
2 {
3 SendClientMessage(playerid, COLOR_RED, "Вы не авторизованы на сервере");
4 return 1;
5 }
6 //Выполнить код команды
Если условие выполнится функция прекратит дальнейшее свое выполнение, то есть все что после нее
будет проигнорировано и функция возвратит true. Также return может возврать какое-либо значение. Взять
например вот такую функцию, которую вы видели на одном из уроков.
1 stock GetName(playerid)
2 {
3 new nick[MAX_PLAYER_NAME];
4 GetPlayerName(playerid, nick, sizeof(nick));
5 return nick;
6 }
Функция возвращает имя игрока, то есть строку содержащее имя игрока. Раз функция возвращает
имя, можно подставлять функцию в любую часть кода где нужно узнать имя игрока, а не переменную
вместо нее, что является оптимизированным способом, чем заводиться для каждой функции переменную.
Урок №30 – Таймер
Таймер – вызывает определённый функцию (public) в определённое время. Функция может
вызваться единожды, либо повторяться через заданные промежутки времени. Для того, чтобы
закрепить таймер на определенной функцией (public), создаётся такая функция:
1 SetTimer("NewFunction",,1);
1 forward NefFunction();
1 public NewFunction(playerid)
2 {
3 print(“Hello, World”);
4 return 1;
5 }
1 SetTimerEx("Say",,1,”s”,”Hello,World”);
1 forward Say(str[]);
1 public Say(str[])
2 {
3 printf("%s",str);
4 return 1;
5 }
В итоге мы каждую секунду передаем строку «Hello, World» в функцию Say, которая
выполняется ежесекундно и отправляет ежесекундно эту строку в консоль сервера.
Урок №32 – Создание сложных команд с помощью dcmd
DCMD - командный процессор, с помощью которого можно более просто (обходя strtok)
создавать команды с параметрами после пробела. Функция создается с помощью константы
(#define). В начале скрипта пишем следующее:
1 #define dcmd(%1,%2,%3) if (!strcmp((%3)[1], #%1, true, (%2)) && ((((%3)[(%2) + 1] == '\0') && (dcmd_%1(playerid, "")))
nest...казино с бесплатным фрибетом Игровой автомат Won Won Rich играть бесплатно ᐈ Игровой Автомат Big Panda Играть Онлайн Бесплатно Amatic™ играть онлайн бесплатно 3 лет Игровой автомат Yamato играть бесплатно рекламе казино vulkan игровые автоматы бесплатно игры онлайн казино на деньги Treasure Island игровой автомат Quickspin казино калигула гта са фото вабанк казино отзывы казино фрэнк синатра slottica казино бездепозитный бонус отзывы мопс казино большое казино монтекарло вкладка с реклама казино вулкан в хроме биткоин казино 999 вулкан россия казино гаминатор игровые автоматы бесплатно лицензионное казино как проверить подлинность CandyLicious игровой автомат Gameplay Interactive Безкоштовний ігровий автомат Just Jewels Deluxe как использовать на 888 poker ставку на казино почему закрывают онлайн казино Игровой автомат Prohibition играть бесплатно