PDA

Просмотр полной версии : [Мануал] Система двигателя. [for new.pwn]



Hidden
16.05.2014, 21:42
Приветствую всех посетивших тему. Как ни странно, этого мануала я не нашёл на портале.

1. Добавляем в начало мода:

#include <a_samp>
#include <foreach>

#define PRESSED(%0) (((newkeys & (%0)) == (%0)) && ((oldkeys & (%0)) != (%0))) // нажатие кнопки
#define COLOR_PURPLE 0xC2A2DAAA // фиолетовый цвет


new engine_car[MAX_VEHICLES char]; // заведена машина / нет
new engine,lights,alarm,bonnet,boot,objective,doors; // перменные для данных о состоянии машины
2. Добавляем в public OnGameModeInit():

ManualVehicleEngineAndLights(); // отключаем автоматическую заводку двигателя
3. Добавляем в public OnPlayerKeyStateChange(playerid, newkeys, oldkeys):

if(PRESSED(KEY_SUBMISSION)) // если нажали цифру "2" на клавиатуре
{
if(!IsPlayerInAnyVehicle(playerid)) return true; // находится ли игрок в машине
if(GetPVarInt(playerid, "Engining") > 0) return true; // начал ли игрок заводку двигателя
new vehicleid = GetPlayerVehicleID(playerid); // создаём переменную, в которую записываем ID машины игрока, чтобы код был менее громоздким
if(GetPlayerState(playerid) != 2) return true; // находится ли игрок за рулём
if(IsABicycle(vehicleid)) return true; // если на велосипеде
new player_name[MAX_PLAYER_NAME]; // переменная для хранения имени игрока
GetPlayerName(playerid, player_name, sizeof(player_name)); // записываем имя игрока в переменную
if(engine_car{vehicleid} == 0) // если двигатель машины не заведён
{
new text[29+MAX_PLAYER_NAME]; // создаём переменную для хранения текста (29 символов данного текста + ячейки для имени игрока)
format(text, sizeof(text), "*%s пытается завести двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
SetTimerEx("RandomEnginingCar", 1500, 0, "%i", playerid); // переменной таймера присваивам запуск таймера
SetPVarInt(playerid, "Engining", 1); // начинаем заводку двигателя
}
else // если двигатель машины заведён
{
engine_car{vehicleid} = 0; // глушим двигатель
new text2[19+MAX_PLAYER_NAME]; // создаём переменную для хранения текста (19 символов данного текста + ячейки для имени игрока)
format(text2, sizeof(text2), "*%s глушит двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text2, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
GetVehicleParamsEx(vehicleid,engine,lights,alarm,doors,bonnet,boot,objective); // получаем данные о состоянии машины
SetVehicleParamsEx(vehicleid,VEHICLE_PARAMS_OFF,lights,alarm,doors,bonnet,boot,objective); // выключаем двигатель
}
}
4. Добавляем в public OnPlayerStateChange(playerid, newstate, oldstate):

if(newstate == PLAYER_STATE_DRIVER) // если игрок сел за руль
{
new vehicleid = GetPlayerVehicleID(playerid); // создаём переменную, в которую записываем ID машины игрока, чтобы код был менее громоздким
if(IsABicycle(vehicleid) || engine_car{vehicleid} != 0)
// если сели на велосипед или переменная, хранящая информацию о двигателе машины, не равна 0
{
GetVehicleParamsEx(vehicleid,engine,lights,alarm,doors,bonnet,boot,objective); // получаем данные о состоянии машины
SetVehicleParamsEx(vehicleid,VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective); // включаем "двигатель
}
}
5. Теперь сам процесс заводки двигателя. В середину/конец мода добавляем:

forward RandomEnginingCar(playerid);
public RandomEnginingCar(playerid)
{
new text[36+MAX_PLAYER_NAME]; // создаём переменную для хранения текста
new vehicleid = GetPlayerVehicleID(playerid); // создаём переменную, в которую записываем ID машины игрока, чтобы код был менее громоздким
new Float: vehicle_health; // создаём переменную для хранения HP машины
GetVehicleHealth(vehicleid, vehicle_health); // записываем HP машины в переменную
new player_name[MAX_PLAYER_NAME]; // переменная для хранения имени игрока
GetPlayerName(playerid, player_name, sizeof(player_name)); // записываем имя игрока в переменную
if(vehicle_health >= 900) // если HP машины больше либо равно 900
{
engine_car{vehicleid} = 1; // заводим машину
GetVehicleParamsEx(vehicleid,engine,lights,alarm,doors,bonnet,boot,objective); // получаем данные о состоянии машины
SetVehicleParamsEx(vehicleid,VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective); // включаем двигатель
format(text, sizeof(text), "*%s заводит двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
}
else if(vehicle_health >= 500 || vehicle_health < 900) // если HP машины от 500 до 900
{
switch(random(5)) // проверяем значения random_engine
{
case 0..3: // если выпали числа 0, 1, 2, 3, двигатель заведётся
{
engine_car{vehicleid} = 1; // заводим машину
GetVehicleParamsEx(vehicleid,engine,lights,alarm,doors,bonnet,boot,objective); // получаем данные о состоянии машины
SetVehicleParamsEx(vehicleid,VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective); // включаем двигатель
format(text, sizeof(text), "*%s заводит двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
}
case 4: // если выпало число 4, двигатель не заведётся
{
format(text, sizeof(text), "*У %s не получилось завести двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
}
}
}
else if(vehicle_health < 500) // если HP машины < 500
{
switch(random(5)) // проверяем значения random_engine
{
case 3, 4: // если выпали числа 3 или 4, то двигатель заведётся
{
engine_car{vehicleid} = 1; // заводим машину
GetVehicleParamsEx(vehicleid,engine,lights,alarm,doors,bonnet,boot,objective); // получаем данные о состоянии машины
SetVehicleParamsEx(vehicleid,VEHICLE_PARAMS_ON,lights,alarm,doors,bonnet,boot,objective); // включаем двигатель
format(text, sizeof(text), "*%s заводит двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
}
case 0..2: // если выпали числа 0, 1, 2, то двигатель не заведётся
{
format(text, sizeof(text), "*У %s не получилось завести двигатель.", player_name); // форматируем текст - записываем вместо %s имя игрока
ProxDetectorEx(15.0, playerid, text, COLOR_PURPLE); // отправляем текст в чат всем, кто находится в 15 метрах от нас (фиолетовым цветом)
}
}
}
SetPVarInt(playerid, "Engining", 0); // процесс заводки авто окончен
return true;
}
6. Нужные стоки (stock):

stock ProxDetectorEx(Float:radi, playerid, string[], color) // отправка сообщения в чат на расстояние
{
new Float:positions[3]; // создаём 3 перменные типа FLOAT (0, 1 и 2) для хранения координат игрока
GetPlayerPos(playerid,positions[0],positions[1],positions[2]); // записываем координаты игрока в переменные
foreach(new i: Player) // перебираем всех игроков
{
if(IsPlayerInRangeOfPoint(i,radi,positions[0],positions[1],positions[2])) // если игрок в указанном радиусе
{
if(GetPlayerVirtualWorld(i) == GetPlayerVirtualWorld(playerid) && GetPlayerInterior(playerid) == GetPlayerInterior(i)) SendClientMessage(i, color, string);
// и имеет такие же виртуальный мир и интерьер, как и у данного игрока, то ему приходит сообщение в чат
}
}
return true;
}

stock IsABicycle(vehicleid) // велосипеды
{
switch(GetVehicleModel(vehicleid)) // проверяем значения модели
{
case 481, 509, 510, 448: return true;
}
return false;
}
7. В public OnVehicleSpawn:

engine_car{vehicleid} = 0;
*Во время респавна автомобиля выключаем ему двигатель.


Постарался всё разъяснить предельно подробно. Если заметили недоработки/ошибки или хотите задать вопрос - оставляйте сообщение ниже.
Автор мануала: Hidden.

wAx
16.05.2014, 22:08
Отредактировал. Автору пару замечаний:


stock SetVehicleToRespawnEx(vehicle)
{
engine_car[vehicle] = 0;
SetVehicleToRespawn(vehicle);
return true;
}

Нет нужды в замене стандартной функции. Достаточно в OnVehicleSpawn приравнивать переменную к 0.


new random_engine[MAX_PLAYERS]; // заведётся / не заведётся

Почему-бы напрямую не использовать функцию random(max) в switch?


new timer_engining[MAX_PLAYERS]; // переменная для таймера
timer_engining[playerid] = SetTimerEx("RandomEnginingCar", 1500, 1, "%i", playerid); // переменной таймера присваивам запуск таймера

Достаточно поставить циклирование таймера на 0 и после выполнения кода таймера - сервер его забудет как страшный сон.
У меня все. По делу: Неплохой урок.

- - - Добавлено - - -

Ах-да, еще в IsABicycle


new model = GetVehicleModel(vehicleid);
зачем использовать переменную? Можно напрямую получить модель в switch

wAx
16.05.2014, 23:06
И random(4) никогда не выдаст 4

Hidden
16.05.2014, 23:25
Безумно благодарен за исправление ошибок. Урок для меня, обязательно учту.

Salvacore
18.06.2014, 21:37
7. В OnVehicleSpawn:


engine_car[vehicle] = 0;
Исправь на vehicleid

DeimoS
19.06.2014, 10:03
И массив тогда лучше перенести на char и работать уже с байтами, а не с ячейками, раз значение может быть только 0 и 1

Hidden
20.06.2014, 01:59
7. В OnVehicleSpawn:


engine_car[vehicle] = 0;
Исправь на vehicleid


И массив тогда лучше перенести на char и работать уже с байтами, а не с ячейками, раз значение может быть только 0 и 1

Внёс поправки. Спасибо.

Salvacore
20.06.2014, 02:25
Ну раз значение только 1 и 0, можно и

new bool:engine_car[MAX_VEHICLES char];

engine_car{vehicleid}= false;

vitalik6243
14.07.2014, 00:46
честно говоря тупо, лучше нажал клавишу и держишь идет звук типо машина пытается завестись id звука где-то был.
но вот вопрос как сделать чтобы OnPlayerKeyStateChange узнавал держу я клавишу или нет...

DeimoS
14.07.2014, 09:10
честно говоря тупо, лучше нажал клавишу и держишь идет звук типо машина пытается завестись id звука где-то был.
но вот вопрос как сделать чтобы OnPlayerKeyStateChange узнавал держу я клавишу или нет...

А параметры newkeys и oldkeys для кого? Узнаём длительность этого вашего звука и запускаем таймер при нажатии на клавишу с тем интервалом, с которым играет наш звук. А после делаем какую-нибудь переменную, по которой будем отлавливать нажатие следующей клавиши и глушим звук. Ну что-то типа


public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
new vehicle_id = GetPlayerVehicleId(playerid);
if(vehicle_id)
{
if(newkeys & KEY_FIRE && !(oldkeys & KEY_FIRE))
{
SetTimerEx("SoundEngine", /*Интервал*/, 0, "i", playerid);
SetPVarInt(playerid, "EngineStartPressed", 1);
//Запускаем наш звук и выполняем другие действия
}
else if(!(oldkeys & KEY_FIRE) && !(newkeys & KEY_FIRE))
{
DeletePVar(playerid, "EngineStartPressed");
}
}
return 1;
}

forward SoundEngine(playerid);
public SoundEngine(playerid)
{
if(Двигатель нужно завести)
{
DeletePVar(playerid, "EngineStartPressed");
//Запускаем двигатель
}
else
{
//Повторно запускаем звук
}
if(GetPVarInt(playerid, "EngineStartPressed")) SetTimerEx("SoundEngine", /*Интервал*/, 0, "i", playerid);
return 1;
}

Но не проверял

vitalik6243
15.07.2014, 11:57
А параметры newkeys и oldkeys для кого? Узнаём длительность этого вашего звука и запускаем таймер при нажатии на клавишу с тем интервалом, с которым играет наш звук. А после делаем какую-нибудь переменную, по которой будем отлавливать нажатие следующей клавиши и глушим звук. Ну что-то типа


public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
new vehicle_id = GetPlayerVehicleId(playerid);
if(vehicle_id)
{
if(newkeys & KEY_FIRE && !(oldkeys & KEY_FIRE))
{
SetTimerEx("SoundEngine", /*Интервал*/, 0, "i", playerid);
SetPVarInt(playerid, "EngineStartPressed", 1);
//Запускаем наш звук и выполняем другие действия
}
else if(!(oldkeys & KEY_FIRE) && !(newkeys & KEY_FIRE))
{
DeletePVar(playerid, "EngineStartPressed");
}
}
return 1;
}

forward SoundEngine(playerid);
public SoundEngine(playerid)
{
if(Двигатель нужно завести)
{
DeletePVar(playerid, "EngineStartPressed");
//Запускаем двигатель
}
else
{
//Повторно запускаем звук
}
if(GetPVarInt(playerid, "EngineStartPressed")) SetTimerEx("SoundEngine", /*Интервал*/, 0, "i", playerid);
return 1;
}

Но не проверял

Хм как вариант.
просто oldkeys не когда не пользовался да и в общем не читал что она выполняет.

gamagama
12.08.2014, 06:37
Большое спасибо,мне очень помог ваш мануал (хотя у меня уже есть готовая написанная система)

NEXT
26.01.2015, 22:07
delll

Hidden
27.01.2015, 18:34
NEXT, Ваш код, безусловно, оставляет желать лучшего. Я с трудом разобрался, что к чему. Пишите, если будут проблемы:

else if(strcmp("/en", cmdtext, true) == 0)
{
new vehicle_ID = GetPlayerVehicleID(playerid);
if(vehicle_ID == INVALID_VEHICLE_ID \
|| GetPlayerState(playerid) != PLAYER_STATE_DRIVER \
|| IsABycicle(vehicle_ID) \
|| GetPVarInt(playerid, "Engining") > 0) return true;
if(vehicle_ID <= MAX_BUYABLE_CARS)
{
if(CarsInfo[vehicle_ID-1][vOwned] == 0) return SendClientMessage(playerid, COLOR_GREY, "Вы должны купить машину, чтобы ездить на ней!");
}
if(IsAArendCar(vehicle_ID))
{
new rentid = GetArendCarID(vehicle_ID);
if(ArendInfo[rentid][aRentID] != playerid) return false;
}
if(zavodis[vehicle_ID] == 0)
{
if(vehicle_ID <= MAX_BUYABLE_CARS && PlayerInfo[playerid][pCarKey] != vehicle_ID-1 && PlayerInfo[playerid][pCarKey2] != vehicle_ID-1) return SendClientMessage(playerid, COLOR_GREY, "У вас нет ключей от этого автомобиля!");
if(vehicle_ID <= MAX_BUYABLE_CARS && CarsInfo[vehicle_ID-1][vShtraf]) return SendClientMessage(playerid, COLOR_GREY, "{ffffff}Ваша машина оштрафована, введите {FF6347}/payshtraf{ffffff} чтобы заплатить штраф");
new Float:hp,
text[29+MAX_PLAYER_NAME];
GetVehicleHealth(vehicle_ID, hp);
if(hp < 400) return SendClientMessage(playerid, -1, "Машина разбита. Двигатель не заводится. Вы можете вызвать механика {FF6347}(/service Вызвать механика)");
if(Fuell[vehicle_ID] <= 0) return SendClientMessage(playerid, -1, "В машине нет бензина. Вы можете вызвать механика {FF6347}(/service Вызвать механика){FFFFFF} или заправьтесь из канистры.");
format(text, sizeof(text), "*%s пытается завести двигатель.", player_name);
ProxDetector(30.0, playerid, text, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
SetTimerEx("RandomEnginingCar", 1500, 0, "%i", playerid);
SetPVarInt(playerid, "Engining", 1);
}
else
{
Engine(vehicle_ID,false);
zavodis[vehicle_ID] = 0;
Lights(vehicle_ID,false);
LightPwr[vehicle_ID] = 0;
new text2[19+MAX_PLAYER_NAME];
format(text2, sizeof(text2), "%s глушит двигатель.", sendername);
ProxDetector(30.0, playerid, text2, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
SetPlayerChatBubble(playerid, text2, COLOR_PURPLE, 30.0, 10000);
if(Signal[vehicle_ID])
{
DestroyObject(LightsObject[vehicle_ID][0]);
DestroyObject(LightsObject[vehicle_ID][1]);
LightsObject[vehicle_ID][0] = -1;
LightsObject[vehicle_ID][1] = -1;
SignalTick[vehicle_ID][0] = 0;
SignalTick[vehicle_ID][1] = -1;
Signal[vehicle_ID] = 0;
}
if(vehicle_ID <= MAX_BUYABLE_CARS && CarsInfo[vehicle_ID-1][vNeon] != 0)
{
DestroyObject(neons[vehicle_ID][0]);
DestroyObject(neons[vehicle_ID][1]);
neons[vehicle_ID][0] = -1;
neons[vehicle_ID][1] = -1;
}
}
return true;
}

//в конец мода
forward RandomEnginingCar(playerid);
public RandomEnginingCar(playerid)
{
new text[36+MAX_PLAYER_NAME],
vehicle_ID = GetPlayerVehicleID(playerid),
Float: vehicle_health,
player_name[MAX_PLAYER_NAME];
GetVehicleHealth(vehicle_ID, vehicle_health);
GetPlayerName(playerid, player_name, sizeof(player_name));
if(vehicle_health >= 900)
{
Engine(vehicle_ID,true);
zavodis[vehicle_ID] = 1;
format(text, sizeof(text), "%s завёл двигатель транспорта.", player_name);
ProxDetector(30.0, playerid, text, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
SetPlayerChatBubble(playerid, text, COLOR_PURPLE,30.0,10000);
if(LightsStatus(vehicle_ID) == 1)
{
LightPwr[vehicle_ID] = 0;
if(vehicle_ID <= MAX_BUYABLE_CARS && CarsInfo[vehicle_ID-1][vNeon] != 0)
{
DestroyObject(neons[vehicle_ID][0]);
DestroyObject(neons[vehicle_ID][1]);
neons[vehicle_ID][0] = -1;
neons[vehicle_ID][1] = -1;
}
}
}
else if(vehicle_health >= 500 || vehicle_health < 900)
{
switch(random(5))
{
case 0..3:
{
Engine(vehicle_ID,true);
zavodis[vehicle_ID] = 1;
format(text, sizeof(text), "%s завёл двигатель транспорта.", player_name);
ProxDetector(30.0, playerid, text, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
SetPlayerChatBubble(playerid, text, COLOR_PURPLE,30.0,10000);
if(LightsStatus(vehicle_ID) == 1)
{
LightPwr[vehicle_ID] = 0;
if(vehicle_ID <= MAX_BUYABLE_CARS && CarsInfo[vehicle_ID-1][vNeon] != 0)
{
DestroyObject(neons[vehicle_ID][0]);
DestroyObject(neons[vehicle_ID][1]);
neons[vehicle_ID][0] = -1;
neons[vehicle_ID][1] = -1;
}
}
}
case 4:
{
format(text, sizeof(text), "*У %s не получилось завести двигатель.", player_name);
ProxDetector(30.0, playerid, text, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
}
}
}
else if(vehicle_health < 500)
{
switch(random(5))
{
case 3, 4:
{
Engine(vehicle_ID,true);
zavodis[vehicle_ID] = 1;
format(text, sizeof(text), "%s завёл двигатель транспорта.", player_name);
ProxDetector(30.0, playerid, text, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
SetPlayerChatBubble(playerid, text, COLOR_PURPLE,30.0,10000);
if(LightsStatus(vehicle_ID) == 1)
{
LightPwr[vehicle_ID] = 0;
if(vehicle_ID <= MAX_BUYABLE_CARS && CarsInfo[vehicle_ID-1][vNeon] != 0)
{
DestroyObject(neons[vehicle_ID][0]);
DestroyObject(neons[vehicle_ID][1]);
neons[vehicle_ID][0] = -1;
neons[vehicle_ID][1] = -1;
}
}
}
case 0..2:
{
format(text, sizeof(text), "*У %s не получилось завести двигатель.", player_name);
ProxDetector(30.0, playerid, text, COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE,COLOR_PURPLE);
}
}
}
SetPVarInt(playerid, "Engining", 0);
return true;
}

А Вам рекомендую почитать рекомендации по написанию кода (в разделе "Уроки" вроде тема), да и другие работы модераторов форума.

NEXT
27.01.2015, 23:34
Hidden
Спасибо вам большое, всё работает как положено (без перебоев) )))
На счёт уроков, да читаю потихоньку хоть что то набирается в свой опыт но этого еще недостаточно))