Професійний форум про pawn-скриптинга

YANS (Yet Another Neon System), або пишемо можливість встановлювати неон з нуля.

Доброго часу доби, шановні користувачі.
Я знаю, що було вже дуже багато рішень по установці неонових вогнів на автомобіль, але тлумачного туторіал з докладним поясненням, як і чому все працює, я не бачив. Що ж, потрібно виправити цю прикру помилку.

Отже, спочатку розберемо принцип роботи.
Як багато хто знає, в SAMP дозволено прикріплювати об'єкти до автомобілів. А оскільки в наявності є об'єкти галогенових ламп, завдання стає найпростішої - при установці неону створюємо об'єкт-лампу і кріпимо його до автомобіля, при демонтажі - видаляємо.
Об'єкти ламп мають ID з 18647 по 18651 (в даному прикладі - червоний, синій, зелений, жовтий і рожевий відповідно).

Як не дивно, але - з теорією все, пора переходити до практики. Створюємо new.pwn, підключаємо бібліотеку a_samp. Для бажаючих - можна підключити і стример, в туторіали будуть використовуватися стандартні функції для роботи з об'єктами.

Оголошуємо масив для зберігання інформації про автомобілі і неонових вогнях. У нульовому елементі буде зберігатися інформація про наявність і кольорі лампи (-1 - не встановлено, від 0 до 4 - відповідно червоний, синій, зелений, жовтий і рожевий), перший і другий будуть використовуватися для зберігання в них покажчиків на об'єкти, останній - для збереження поточного стану лампи (включена або виключена).

new neon # 91; MAX_VEHICLES # 93; # 91; 4 # 93 ;;

Тепер приступимо до основних функцій. Першою з них буде установка неону на автомобіль. Параметрами функції будуть ID автомобіля в грі і колір від 0 до 4 - при створенні об'єкта 18647 буде зрушуватися на значення кольору (18647 - об'єкт червоною лампи). Алгоритм такий: нульового елементу присвоюємо значення кольору, третій - одиницю (лампа після установки включена), створюються два об'єкти (перший і другий елементи) і прикріплюються до автомобіля.

forward PlaceNeon (vehicle. color);
public PlaceNeon (vehicle. color)
neon # 91; vehicle # 93; # 91; 0 # 93; = Color;
neon # 91; vehicle # 93; # 91; 3 # 93; = 1;
DestroyObject (neon # 91; vehicle # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicle # 93; # 91; 2 # 93;);
neon # 91; vehicle # 93; # 91; 1 # 93; = CreateObject (18647 + color. 0. 0. 0. 0. 0. 0. 100.0);
neon # 91; vehicle # 93; # 91; 2 # 93; = CreateObject (18647 + color. 0. 0. 0. 0. 0. 0. 100.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 1 # 93 ;, vehicle. - 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 2 # 93 ;, vehicle. 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
return 1;
>

Далі йде видалення неону. Функція приймає як параметр тільки ID авто. Ставимо в нульовий елемент -1 (відсутність неону), лампу вимикаємо (третій елемент в нуль), об'єкти видаляємо.

forward RemoveNeon (vehicle);
public RemoveNeon (vehicle)
neon # 91; vehicle # 93; # 91; 0 # 93; = - 1;
neon # 91; vehicle # 93; # 91; 3 # 93; = 0;
DestroyObject (neon # 91; vehicle # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicle # 93; # 91; 2 # 93;);
return 1;
>

Остання функція - включення-виключення встановленої лампи. Тут алгоритм складніше.
Якщо лампа встановлена ​​(перший елемент масиву - НЕ -1), починає свою роботу тригер. Якщо лампа була виключена - створюємо два об'єкти потрібного кольору. Якщо включена - видаляємо їх. Природно, не забуваючи ставити потрібні мітки в стан лампи.

forward TurnNeon (vehicle);
public TurnNeon (vehicle)
if (neon # 91; vehicle # 93; # 91; 0 # 93; ! = - 1)
switch (neon # 91; vehicle # 93; # 91; 3 # 93;)
case 0:
neon # 91; vehicle # 93; # 91; 3 # 93; = 1;
neon # 91; vehicle # 93; # 91; 1 # 93; = CreateObject (18647 + neon # 91; vehicle # 93; # 91; 0 # 93 ;, 0. 0. 0. 0. 0. 0. 100.0);
neon # 91; vehicle # 93; # 91; 2 # 93; = CreateObject (18647 + neon # 91; vehicle # 93; # 91; 0 # 93 ;, 0. 0. 0. 0. 0. 0. 100.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 1 # 93 ;, vehicle. - 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 2 # 93 ;, vehicle. 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
>
case 1:
neon # 91; vehicle # 93; # 91; 3 # 93; = 0;
DestroyObject (neon # 91; vehicle # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicle # 93; # 91; 2 # 93;);
>
>
>
return 1;
>

Власне, основні функції у нас є. Як з ними працювати - вже як підкаже фантазія, але я розберу конкретні приклади.
Отже, установка буде проходити по команді / neon. Створюємо діалогове вікно зі списком. Прошу не штовхати за те, що в першому меню всього один пункт - писалося з запасом, так як буде доповнюватися мішурою типу установки мигалок і так далі.

public OnPlayerCommandText (playerid. cmdtext # 91; # 93;)
if (! strcmp ( "/ neon". cmdtext. true))
if (IsPlayerInAnyVehicle (playerid))
if (GetPlayerState (playerid)! = PLAYER_STATE_DRIVER) SendClientMessage (playerid. 0xAFAFAFAA. "Ви повинні сидіти за кермом автомобіля");
else ShowPlayerDialog (playerid. 6000. DIALOG_STYLE_LIST. "Меню". "Неон". "Вибрати". "Скасування");
>
return 1;
>
return 0;
>

public OnDialogResponse (playerid. dialogid. response. listitem. inputtext # 91; # 93;)
if (dialogid == 6000)
if (response)
if (listitem == 0) ShowPlayerDialog (playerid. 6001. DIALOG_STYLE_LIST. "Неон". "Червоний \ nСіній \ nЗелений \ nЖелтий \ nРозовий \ nУбрать неон". "Далі". "Скасування");
>
return 1;
>
if (dialogid == 6001)
if (response)
if (listitem == 5)
RemoveNeon (GetPlayerVehicleID (playerid));
SendClientMessage (playerid. 0xff440000. "Неон видалений");
>
else if (listitem> = 0 listitem <= 4 )
PlaceNeon (GetPlayerVehicleID (playerid), listitem);
SendClientMessage (playerid. 0xff440000. "Неон встановлений");
>
>
return 1;
>
return 0;
>

Включення-виключення заб'ємо на кнопку подміссій (стандартно - 2 на алфавітній частині клавіатури). Використовуємо старий-добрий дефайн PRESSED:

#define PRESSED (% 0) (((newkeys (% 0)) == (% 0)) ((Oldkeys (% 0))! = (% 0)))

І, власне, описуємо дії по кнопці:

public OnPlayerKeyStateChange (playerid. newkeys. oldkeys)
if (PRESSED (512) GetPlayerState (playerid) == PLAYER_STATE_DRIVER) TurnNeon (GetPlayerVehicleID (playerid));
return 1;
>

А що робити, якщо машина знищиться? Об'єкти треба видалити. Використовуємо OnVehicleDeath:

public OnVehicleDeath (vehicleid. killerid)
DestroyObject (neon # 91; vehicleid # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicleid # 93; # 91; 2 # 93;);
return 1;
>

І для грамотної завантаження і вивантаження об'єктів - вичищаємо масиви при старті і при зупинці скрипта.

public OnFilterScriptInit ()
for (new i = 0; i return 1;
>

public OnFilterScriptExit ()
for (new i = 0; i return 1;
>

Власне, все! Після складання в купу код набуває ось такий вигляд:


#define PRESSED (% 0) (((newkeys (% 0)) == (% 0)) ((Oldkeys (% 0))! = (% 0)))

// Масив для обробки. 0 - наявність (і колір) неону (-1 - не встановлений), 1 і 2 - об'єкти, 3 - стан (вкл-викл)
new neon # 91; MAX_VEHICLES # 93; # 91; 4 # 93 ;;

// Форварди для функцій
forward PlaceNeon (vehicle. color);
forward RemoveNeon (vehicle);
forward TurnNeon (vehicle);

// Завантаження скрипта. На всякий пожежний - підчищення інформації в масиві.
public OnFilterScriptInit ()
for (new i = 0; i return 1;
>

// Вивантаження скрипта. Очищення масиву.
public OnFilterScriptExit ()
for (new i = 0; i return 1;
>

public OnPlayerCommandText (playerid. cmdtext # 91; # 93;)
if (strcmp ( "/ neon". cmdtext. true. 10) == 0)
if (IsPlayerInAnyVehicle (playerid))
if (GetPlayerState (playerid)! = PLAYER_STATE_DRIVER) SendClientMessage (playerid. 0xAFAFAFAA. "Ви повинні сидіти за кермом автомобіля");
else ShowPlayerDialog (playerid. 6000. DIALOG_STYLE_LIST. "Меню". "Неон". "Вибрати". "Скасування");
>
return 1;
>
return 0;
>

public OnDialogResponse (playerid. dialogid. response. listitem. inputtext # 91; # 93;)
if (dialogid == 6000)
if (response)
if (listitem == 0) ShowPlayerDialog (playerid. 6001. DIALOG_STYLE_LIST. "Неон". "Червоний \ nСіній \ nЗелений \ nЖелтий \ nРозовий \ nУбрать неон". "Далі". "Скасування");
>
return 1;
>
if (dialogid == 6001)
if (response)
if (listitem == 5)
RemoveNeon (GetPlayerVehicleID (playerid));
SendClientMessage (playerid. 0xff440000. "Неон видалений");
>
else if (listitem> = 0 listitem <= 4 )
PlaceNeon (GetPlayerVehicleID (playerid), listitem);
SendClientMessage (playerid. 0xff440000. "Неон встановлений");
>
>
return 1;
>
return 0;
>

public OnPlayerKeyStateChange (playerid. newkeys. oldkeys)
if (PRESSED (512) GetPlayerState (playerid) == PLAYER_STATE_DRIVER) TurnNeon (GetPlayerVehicleID (playerid));
return 1;
>

public OnVehicleDeath (vehicleid. killerid)
DestroyObject (neon # 91; vehicleid # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicleid # 93; # 91; 2 # 93;);
return 1;
>

// Установка неону. Параметри - ID авто і колір.
public PlaceNeon (vehicle. color)
neon # 91; vehicle # 93; # 91; 0 # 93; = Color;
neon # 91; vehicle # 93; # 91; 3 # 93; = 1;
DestroyObject (neon # 91; vehicle # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicle # 93; # 91; 2 # 93;);
neon # 91; vehicle # 93; # 91; 1 # 93; = CreateObject (18647 + color. 0. 0. 0. 0. 0. 0. 100.0);
neon # 91; vehicle # 93; # 91; 2 # 93; = CreateObject (18647 + color. 0. 0. 0. 0. 0. 0. 100.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 1 # 93 ;, vehicle. - 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 2 # 93 ;, vehicle. 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
return 1;
>

// Видалення неону
public RemoveNeon (vehicle)
neon # 91; vehicle # 93; # 91; 0 # 93; = - 1;
neon # 91; vehicle # 93; # 91; 3 # 93; = 0;
DestroyObject (neon # 91; vehicle # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicle # 93; # 91; 2 # 93;);
return 1;
>

// Управління неоном
public TurnNeon (vehicle)
if (neon # 91; vehicle # 93; # 91; 0 # 93; ! = - 1)
switch (neon # 91; vehicle # 93; # 91; 3 # 93;)
case 0:
neon # 91; vehicle # 93; # 91; 3 # 93; = 1;
neon # 91; vehicle # 93; # 91; 1 # 93; = CreateObject (18647 + neon # 91; vehicle # 93; # 91; 0 # 93 ;, 0. 0. 0. 0. 0. 0. 100.0);
neon # 91; vehicle # 93; # 91; 2 # 93; = CreateObject (18647 + neon # 91; vehicle # 93; # 91; 0 # 93 ;, 0. 0. 0. 0. 0. 0. 100.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 1 # 93 ;, vehicle. - 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
AttachObjectToVehicle (neon # 91; vehicle # 93; # 91; 2 # 93 ;, vehicle. 0.8. 0.0. - 0.70. 0.0. 0.0. 0.0);
>
case 1:
neon # 91; vehicle # 93; # 91; 3 # 93; = 0;
DestroyObject (neon # 91; vehicle # 93; # 91; 1 # 93;);
DestroyObject (neon # 91; vehicle # 93; # 91; 2 # 93;);
>
>
>
return 1;
>


Я не розглядав в даному прикладі збереження параметрів неону після вивантаження сервера у файлі або БД, перевірку на те, в авто чи гравець або в мотоциклі / вертольоті / etc. і тому подібні речі. Як видно з коду, за установку навіть гроші не знімаються. В цьому і полягає універсальність - можна заточити исходник під власні потреби.

Прошу не штовхати за можливі ділянки бидлокод, неоптимальні рішення і так далі. Пропозиції та конструктивну критику з задоволенням прийму в даній темі.

Re: YANS (Yet Another Neon System), або пишемо можливість встановлювати неон з нуля.

Але якщо вже все про неон пишеш, то напиши про можливість змішувати кольору

Re: YANS (Yet Another Neon System), або пишемо можливість встановлювати неон з нуля.

Тут змішування немає, перед установкою в будь-якому випадку проходить DestroyObject.

Re: YANS (Yet Another Neon System), або пишемо можливість встановлювати неон з нуля.

Ще б перевірку на існування об'єкта.

Re: YANS (Yet Another Neon System), або пишемо можливість встановлювати неон з нуля.

У сенсі на існування авто на сервері? Сенсу в ній немає, установка пройде, тільки якщо гравець на водійському місці.
Або Ви про вже наявність встановленого неону? Можна перевіряти за нульовою осередку масиву. Там же розписано - якщо -1, значить, неонка не встановлена, якщо від 0 до 4 - то встановлена ​​певного кольору. Така перевірка в TurnNeon () є.

Re: YANS (Yet Another Neon System), або пишемо можливість встановлювати неон з нуля.

Неї, я говорю про IsValidObject. Адже якщо ліміт об'єктів вичерпаний, то об'єкт не створюється.

Схожі статті