PDA

Просмотр полной версии : [Вопрос] Неверный алгоритм работы кода



punkochel
06.02.2020, 10:16
Уже вторые сутки не могу разобраться с ситуацией. При первичном входе на сервер, когда я сажусь в автомобиль и нажимаю "2", то выполняются функции garage и vehicle одновременно, хотя по идее должна выполниться только одна из них и вероятнее всего это garage (т.к. выполнение ее стоит впереди выполнения vehicle).
Я грешил сначала на неверный возврат одной из функций (думал что возвращает где-то false), но при повторном вызове OnPlayerKeyStateChange - все работает как нужно, а именно, выполняется функция garage, а vehicle уже не выполняется.

Это код вызова функций:

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if (garage_OnPlayerKeyStateChange(playerid, newkeys)) {
return 1;
}
if (vehicle_OnPlayerKeyStateChange(playerid, newkeys)) {
return 1;
}
//etc
return 1;
}

Это код функции vehicle_OnPlayerKeyStateChange:

vehicle_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
return callcmd::engine(playerid);
}
return 0;
}

Это код выполнения функции garage_OnPlayerKeyStateChange:

garage_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(true)
{
for(new i; i < MAX_VEHICLE_PLAYER; i++)
{
if(true)
{
if(true)
{
printf("выполнено");
return 1;
}
else
{
printf("не выполнено");
return 1;
}
}
}
}
}
return 0;
}

Попробовал сделать без создания отдельных функций, а впихнул код в колбэк - все работает как нужно (в том числе и с первичного входа).
Код:

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(true)
{
for(new i; i < MAX_VEHICLE_PLAYER; i++)
{
if(true)
{
if(true)
{
printf("выполнено");
return 1;
}
else
{
printf("не выполнено");
return 1;
}
}
}
}
}
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
return callcmd::engine(playerid);
}
//etc
return 1;
}

L0ndl3m
06.02.2020, 10:31
В команде "engine" есть возврат единицы? Есть предположение, что обе функции всегда возвращают ноль. Первое условие не сработало, и начала выполняться следующая проверка.

Pa4enka
06.02.2020, 11:30
if (0 == garage_OnPlayerKeyStateChange(playerid, newkeys)) {
return 1;
}
if (0 == vehicle_OnPlayerKeyStateChange(playerid, newkeys)) {
return 1;
}

L0ndl3m
06.02.2020, 11:56
Pa4enka, смысл тогда проверять возвращаемое значений функций, если оно всегда возвращает 0?

Pa4enka
06.02.2020, 12:05
Pa4enka, смысл тогда проверять возвращаемое значений функций, если оно всегда возвращает 0?

0 будет возвращён, если проверка в стоке не пройдет. В ином случае, функция возвратит 1, исходя из его кода.

L0ndl3m
06.02.2020, 12:55
0 будет возвращён, если проверка в стоке не пройдет. В ином случае, функция возвратит 1, исходя из его кода.
Не факт, что
return callcmd::engine(playerid);
вернёт 1. Если команда возвращает нуль, то при любом раскладе "сток" вернёт 0, независимо от проверок.
Поэтому я и спросил у ТС:

В команде "engine" есть возврат единицы?

Pa4enka
06.02.2020, 14:21
Если команда возвращает нуль, то при любом раскладе "сток" вернёт 0, независимо от проверок.

Если команда возвращает 0, то она, как минимум, не сработает, разве нет?)
А кто-то в наше время возвращает 0? Ниразу такого не видел.

DeimoS
06.02.2020, 17:15
Если команда возвращает 0, то она, как минимум, не сработает, разве нет?)
А кто-то в наше время возвращает 0? Ниразу такого не видел.

Ты и нормальной работы с MySQL не увидишь в паблик-работах :)

А возврат нуля нужен для того, чтоб плагин не прекращал поиск команды. Например, это может быть полезно в FS, делая своеобразный перехват команды из мода (сначала будет срабатывать команды из скриптов, а потом уже из мода).

Так же возвращаемое значение передаётся в OnPlayerCommandPerformed, в параметр "result". При том, это не обязательно может быть 0 или 1. И это может быть полезно для создания различных сообщений об ошибке. То бишь, чтоб не плодить в каждой команде свой текст ошибки, сделать так:
CMD:pay(playerid, params[])
{
new giveplayerid, money;
if(sscanf(params, "ri", giveplayerid, money))
return SendClientMessage(playerid, 0x888888FF, "Использование: /pay [ID игрока] [Сумма]");
if(giveplayerid == INVALID_PLAYER_ID)
return 2;
if(money < 1)
return 3;
GivePlayerMoney(playerid, money);
return 1;
}



CMD:tpto(playerid, params[])
{
new giveplayerid;
if(sscanf(params, "r", giveplayerid))
return SendClientMessage(playerid, 0x888888FF, "Использование: /tpto [ID игрока]");
if(giveplayerid == INVALID_PLAYER_ID)
return 2;
new Float:x, Float:y, Float:z;
GetPlayerPos(giveplayerid, x, y, z);
SetPlayerPos(playerid, x, y, z);
return 1;
}

public OnPlayerCommandPerformed(playerid, cmd[], params[], result, flags)
{
switch(result)
{
case 1:// Если команда найдена и успешно выполнена (в команде возвращена единица)
return 1;// Прекращаем поиск команды в других скриптах

case 2:// Если в команде возвращена двойка
{
SendClientMessage(playerid, 0x888888FF, "Ошибка: Указанный игрок не найден!");// Показываем сообщение
return 1;// Прекращаем поиск команды в других скриптах
}
case 3:// Если тройка
{
SendClientMessage(playerid, 0x888888FF, "Ошибка: Введено невалидное значение!");// Сообщение
return 1;// Прекращаем поиск команды в других скриптах
}
}
return 0;// Иначе "говорим" плагину продолжать поиск в других скриптах
}
В идеале, конечно, код ошибок обёртывать в именные константы, например, через enum, и уже использовать их, чтоб не запоминать ворох чисел. Я числа указал лишь для наглядности :)


Ну а касаемо случая автора - 0 может возвращаться просто по незнанию (автор для красоты влепил "return false;" при сообщении об ошибке, например, что можно встретить во всяких паблик-модах).

punkochel
06.02.2020, 19:01
В команде "engine" есть возврат единицы? Есть предположение, что обе функции всегда возвращают ноль. Первое условие не сработало, и начала выполняться следующая проверка.

Без разницы что возвращает "engine", сама конструкция return callcmd::engine(playerid); вернет 1, как не крути. В engine есть возврат единицы, но это никак не повлияет на возврат значения из сток.



Ну а касаемо случая автора - 0 может возвращаться просто по незнанию (автор для красоты влепил "return false;" при сообщении об ошибке, например, что можно встретить во всяких паблик-модах).

Не увидел у себя в коде "return false". Единицу сток возвращает в случае успешного выполнения, иначе 0. В случае с проверкой, проверяется именно значение true (1), и если (false(0)), то переходим к следующему условию.
Пример конечно хороший, спасибо, но он никак не отвечает моему запросу.

Я не могу понять почему после авторизации, при вызове колбека KeyStateChange (нажатии на 2), обе функции vehicle и garage выполняются. По идее должно быть так, когда нажал на "2" - идет выполнение garage, если garage вернул 1, то vehicle уже не выполняется, так как колбэк вернул значение больше 0 (то бишь остановил дальнейшую работу). Но в моем случае после авторизации срабатываю обе функции.

DeimoS
06.02.2020, 19:05
Без разницы что возвращает "engine", сама конструкция return callcmd::engine(playerid); вернет 1, как не крути. В engine есть возврат единицы, но это никак не повлияет на возврат значения из сток.




Не увидел у себя в коде "return false". Единицу сток возвращает в случае успешного выполнения, иначе 0. В случае с проверкой, проверяется именно значение true (1), и если (false(0)), то переходим к следующему условию.
Пример конечно хороший, спасибо, но он никак не отвечает моему запросу.

Я не могу понять почему после авторизации, при вызове колбека KeyStateChange (нажатии на 2), обе функции vehicle и garage выполняются. По идее должно быть так, когда нажал на "2" - идет выполнение garage, если garage вернул 1, то vehicle уже не выполняется, так как колбэк вернул значение больше 0 (то бишь остановил дальнейшую работу). Но в моем случае после авторизации срабатываю обе функции.

Скинь весь код, связанный с проблемой, целиком: начиная с команды и заканчивая функциями.

punkochel
06.02.2020, 19:10
Скинь весь код, связанный с проблемой, целиком: начиная с команды и заканчивая функциями.

Callback
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if (vehicle_OnPlayerKeyStateChange(playerid, newkeys)) {
return 1;
}
if (garage_OnPlayerKeyStateChange(playerid, newkeys)) {
return 1;
}
return 1;
}

vehicle_OnPlayerKeyStateChange:
vehicle_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVehicleID(playerid) == PlayerVehicleID[playerid])
{
return callcmd::engine(playerid);
}
}
return 0;
}

garage_OnPlayerKeyStateChange:
garage_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVirtualWorld(playerid) == PlayerInfo[playerid][pHouseID])
{
for(new i; i < MAX_VEHICLE_PLAYER; i++)
{
if(IsPlayerInVehicle(playerid, PlayerInfo[playerid][pVehicle][i]))
{
if(PlayerVehicleID[playerid] == 0)
{
PlayerVehicleID[playerid] = PlayerInfo[playerid][pVehicle][i];
SetVehicleVirtualWorld(PlayerVehicleID[playerid], 0);
LinkVehicleToInterior(PlayerVehicleID[playerid], 0);
SetVehiclePos(PlayerVehicleID[playerid], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosX], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosY], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosZ]);
SetVehicleZAngle(PlayerVehicleID[playerid], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosFacingAngle]);
SetPlayerVirtualWorld(playerid, 0);
SetPlayerInterior(playerid, 0);
PutPlayerInVehicle(playerid, PlayerVehicleID[playerid], 0);
return 1;
}
else
{
SCMError(playerid, "Для смены транспорта, все автомобили должны находится в гараже. Введите: /fixcar");
return 1;
}
}
}
}
}
return 0;
}

cmd:
CMD:engine(playerid)
{
new Float:carhp, engine, lights, alarm, doors, bonnet, boot, objective;
if(GetPlayerVehicleID(playerid) == INVALID_VEHICLE_ID) return 1;
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER) return 1;
GetVehicleParamsEx(GetPlayerVehicleID(playerid), engine, lights, alarm, doors, bonnet, boot, objective);
GetVehicleHealth(GetPlayerVehicleID(playerid), carhp);
if(engine == 0)
{
if(VehicleInfo[GetPlayerVehicleID(playerid)][vFuel] <= 0)
{
return 1;
}
else if(carhp <= 300.0)
{
return 1;
}
}
return 1;
}

DeimoS
06.02.2020, 19:51
if(GetPlayerVehicleID(playerid) == INVALID_VEHICLE_ID) return 1;
Эта проверка неправильная. GetPlayerVehicleID не возвращает INVALID_VEHICLE_ID.



if(GetPlayerVehicleID(playerid) == PlayerVehicleID[playerid])

Если в PlayerVehicleID хранится ID авто, в котором сидит игрок, то зачем? GetPlayerVehicleID хранит ту же самую информацию.



if(newkeys == KEY_SUBMISSION

Если у тебя не стоит задачи сделать вызов функции только когда игрок жмёт только кнопку "2", не нажимая других кнопок, то проверка должна выглядеть так:

if(newkeys & KEY_SUBMISSION

Хотя вообще код крайне странно организован. Зачем в каждой функции прописывать проверку нажатия клавиши, если проверку можно вынести в OnPlayerKeyStateChange и уже, в зависимости от нажатой кнопки, вызывать ту или иную функцию?



Сделай так и скинь логи после нажатия:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
printf("\n\nOnPlayerKeyStateChange(%d, %d, %d)", playerid, newkeys, oldkeys);
new result;

result = vehicle_OnPlayerKeyStateChange(playerid, newkeys);
printf("vehicle_OnPlayerKeyStateChange", result);

if (result) {
return 1;
}

result = garage_OnPlayerKeyStateChange(playerid, newkeys);
printf("garage_OnPlayerKeyStateChange", result);

if (result) {
return 1;
}
return 1;
}

punkochel
06.02.2020, 20:15
Если в PlayerVehicleID хранится ID авто, в котором сидит игрок, то зачем? GetPlayerVehicleID хранит ту же самую информацию.
PlayerVehicleID не хранит ID авто в котором сидит игрок, она хранит ID авто которое выбрал игрок.


Хотя вообще код крайне странно организован. Зачем в каждой функции прописывать проверку нажатия клавиши, если проверку можно вынести в OnPlayerKeyStateChange и уже, в зависимости от нажатой кнопки, вызывать ту или иную функцию?

Не подойдет, потому-что допустим в garage_KeyStateChange есть 2 проверки на кнопки, к примеру:
garage_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys & KEY_SUBMISSION)
{
return 1;
}
if(newkeys & KEY_CROUCH)
{
return 1;
}
return 0;
}


Сделай так и скинь логи после нажатия:


OnPlayerKeyStateChange(0, 16, 0)
[19:14:40] vehicle_OnPlayerKeyStateChange
[19:14:40] garage_OnPlayerKeyStateChange
[19:14:40]

OnPlayerKeyStateChange(0, 0, 16)
[19:14:40] vehicle_OnPlayerKeyStateChange
[19:14:40] garage_OnPlayerKeyStateChange
[19:14:43]

OnPlayerKeyStateChange(0, 8, 0)
[19:14:43] vehicle_OnPlayerKeyStateChange
[19:14:43] garage_OnPlayerKeyStateChange
[19:14:44]

OnPlayerKeyStateChange(0, 0, 8)
[19:14:44] vehicle_OnPlayerKeyStateChange
[19:14:44] garage_OnPlayerKeyStateChange
[19:14:45]

OnPlayerKeyStateChange(0, 16, 0)
[19:14:45] vehicle_OnPlayerKeyStateChange
[19:14:45] garage_OnPlayerKeyStateChange
[19:14:45]

OnPlayerKeyStateChange(0, 0, 16)
[19:14:45] vehicle_OnPlayerKeyStateChange
[19:14:45] garage_OnPlayerKeyStateChange
[19:14:49]

OnPlayerKeyStateChange(0, 512, 0)
[19:14:49] vehicle_OnPlayerKeyStateChange
[19:14:49] garage_OnPlayerKeyStateChange
[19:14:49]

OnPlayerKeyStateChange(0, 0, 512)
[19:14:49] vehicle_OnPlayerKeyStateChange
[19:14:49] garage_OnPlayerKeyStateChange
[19:14:49]

OnPlayerKeyStateChange(0, 512, 0)
[19:14:49] vehicle_OnPlayerKeyStateChange
[19:14:49]

OnPlayerKeyStateChange(0, 0, 512)
[19:14:49] vehicle_OnPlayerKeyStateChange
[19:14:49] garage_OnPlayerKeyStateChange
[19:14:53]

OnPlayerKeyStateChange(0, 4, 0)
[19:14:53] vehicle_OnPlayerKeyStateChange
[19:14:53] garage_OnPlayerKeyStateChange

Pa4enka
06.02.2020, 20:37
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
printf("\n\nOnPlayerKeyStateChange(%d, %d, %d)", playerid, newkeys, oldkeys);
new result;

result = vehicle_OnPlayerKeyStateChange(playerid, newkeys);
printf("vehicle_OnPlayerKeyStateChange: %d", result);

if (result) {
return 1;
}

result = garage_OnPlayerKeyStateChange(playerid, newkeys);
printf("garage_OnPlayerKeyStateChange: %d", result);

if (result) {
return 1;
}
return 1;
}

Подправил код DeimoS'a.

DeimoS
06.02.2020, 20:56
Не подойдет, потому-что допустим в garage_KeyStateChange есть 2 проверки на кнопки, к примеру:
garage_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys & KEY_SUBMISSION)
{
return 1;
}
if(newkeys & KEY_CROUCH)
{
return 1;
}
return 0;
}


Создай 2 функции. В чём проблема?
Такой реализацией у тебя куча лишних действий будет впустую каждое срабатывание OnPlayerKeyStateChange.




Подправил код DeimoS'a.

Да, спасибо. Тупанул :D

punkochel
06.02.2020, 22:45
Я чет вообще курю, ладно бы мод бы переполнен разным функционалом, так ведь он чист. Осталось только на new.pawn попробовать.
Вот в этой ситуации выполняется функция что в if и в else:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(newkeys & KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVirtualWorld(playerid) == PlayerInfo[playerid][pHouseID])
{
for(new i; i < MAX_VEHICLE_PLAYER; i++)
{
if(IsPlayerInVehicle(playerid, PlayerInfo[playerid][pVehicle][i]))
{
if(PlayerVehicleID[playerid] == 0)
{
PlayerVehicleID[playerid] = PlayerInfo[playerid][pVehicle][i];
SetVehicleVirtualWorld(PlayerVehicleID[playerid], 0);
LinkVehicleToInterior(PlayerVehicleID[playerid], 0);
SetVehiclePos(PlayerVehicleID[playerid], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosX], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosY], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosZ]);
SetVehicleZAngle(PlayerVehicleID[playerid], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosFacingAngle]);
SetPlayerVirtualWorld(playerid, 0);
SetPlayerInterior(playerid, 0);
PutPlayerInVehicle(playerid, PlayerVehicleID[playerid], 0);
return 1;
}
else
{
SCMError(playerid, "Для смены транспорта, все автомобили должны находится в гараже. Введите: /fixcar");
return 1;
}
}
}
}
else
{
new Float:carhp, engine, lights, alarm, doors, bonnet, boot, objective;
if(!IsPlayerInAnyVehicle(playerid)) return 1;
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER) return 1;
GetVehicleParamsEx(GetPlayerVehicleID(playerid), engine, lights, alarm, doors, bonnet, boot, objective);
GetVehicleHealth(GetPlayerVehicleID(playerid), carhp);
if(engine == 0)
{
if(VehicleInfo[GetPlayerVehicleID(playerid)][vFuel] <= 0)
{
GameTextForPlayer(playerid,"~r~FUEL TANK IS EMPTY", 3000, 3);
return 1;
}
else if(carhp <= 300.0)
{
GameTextForPlayer(playerid,"~r~ENGINE DAMAGED", 3000, 3);
return 1;
}
SetVehicleParamsEx(GetPlayerVehicleID(playerid), true, true, alarm, doors, bonnet, boot, objective);
}
else
{
SetVehicleParamsEx(GetPlayerVehicleID(playerid), false, false, alarm, doors, bonnet, boot, objective);
}
return 1;
}
}
return 1;
}

DeimoS
07.02.2020, 13:04
Я чет вообще курю, ладно бы мод бы переполнен разным функционалом, так ведь он чист. Осталось только на new.pawn попробовать.
Вот в этой ситуации выполняется функция что в if и в else:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
if(newkeys & KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVirtualWorld(playerid) == PlayerInfo[playerid][pHouseID])
{
for(new i; i < MAX_VEHICLE_PLAYER; i++)
{
if(IsPlayerInVehicle(playerid, PlayerInfo[playerid][pVehicle][i]))
{
if(PlayerVehicleID[playerid] == 0)
{
PlayerVehicleID[playerid] = PlayerInfo[playerid][pVehicle][i];
SetVehicleVirtualWorld(PlayerVehicleID[playerid], 0);
LinkVehicleToInterior(PlayerVehicleID[playerid], 0);
SetVehiclePos(PlayerVehicleID[playerid], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosX], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosY], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosZ]);
SetVehicleZAngle(PlayerVehicleID[playerid], HouseInfo[PlayerInfo[playerid][pHouseID]][hCarPosFacingAngle]);
SetPlayerVirtualWorld(playerid, 0);
SetPlayerInterior(playerid, 0);
PutPlayerInVehicle(playerid, PlayerVehicleID[playerid], 0);
return 1;
}
else
{
SCMError(playerid, "Для смены транспорта, все автомобили должны находится в гараже. Введите: /fixcar");
return 1;
}
}
}
}
else
{
new Float:carhp, engine, lights, alarm, doors, bonnet, boot, objective;
if(!IsPlayerInAnyVehicle(playerid)) return 1;
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER) return 1;
GetVehicleParamsEx(GetPlayerVehicleID(playerid), engine, lights, alarm, doors, bonnet, boot, objective);
GetVehicleHealth(GetPlayerVehicleID(playerid), carhp);
if(engine == 0)
{
if(VehicleInfo[GetPlayerVehicleID(playerid)][vFuel] <= 0)
{
GameTextForPlayer(playerid,"~r~FUEL TANK IS EMPTY", 3000, 3);
return 1;
}
else if(carhp <= 300.0)
{
GameTextForPlayer(playerid,"~r~ENGINE DAMAGED", 3000, 3);
return 1;
}
SetVehicleParamsEx(GetPlayerVehicleID(playerid), true, true, alarm, doors, bonnet, boot, objective);
}
else
{
SetVehicleParamsEx(GetPlayerVehicleID(playerid), false, false, alarm, doors, bonnet, boot, objective);
}
return 1;
}
}
return 1;
}

Если это сообщение о твоей изначальной проблеме, то Pa4enka выше скинул код, который так же нужно протестировать и скинуть логи.

punkochel
07.02.2020, 18:07
Если это сообщение о твоей изначальной проблеме, то Pa4enka выше скинул код, который так же нужно протестировать и скинуть логи.


OnPlayerKeyStateChange(0, 16, 0)
[17:06:52] vehicle_OnPlayerKeyStateChange: 0
[17:06:52] garage_OnPlayerKeyStateChange: 0
[17:06:52]

OnPlayerKeyStateChange(0, 0, 16)
[17:06:52] vehicle_OnPlayerKeyStateChange: 0
[17:06:52] garage_OnPlayerKeyStateChange: 0
[17:06:56]

OnPlayerKeyStateChange(0, 16, 0)
[17:06:56] vehicle_OnPlayerKeyStateChange: 0
[17:06:56] garage_OnPlayerKeyStateChange: 0
[17:06:56]

OnPlayerKeyStateChange(0, 0, 16)
[17:06:56] vehicle_OnPlayerKeyStateChange: 0
[17:06:56] garage_OnPlayerKeyStateChange: 0
[17:07:02]

OnPlayerKeyStateChange(0, 512, 0)
[17:07:02] vehicle_OnPlayerKeyStateChange: 0
[17:07:02] garage_OnPlayerKeyStateChange: 1
[17:07:02]

OnPlayerKeyStateChange(0, 0, 512)
[17:07:02] vehicle_OnPlayerKeyStateChange: 0
[17:07:02] garage_OnPlayerKeyStateChange: 0
[17:07:02]

OnPlayerKeyStateChange(0, 512, 0)
[17:07:02] vehicle_OnPlayerKeyStateChange: 1
[17:07:02]

OnPlayerKeyStateChange(0, 0, 512)
[17:07:02] vehicle_OnPlayerKeyStateChange: 0
[17:07:02] garage_OnPlayerKeyStateChange: 0
[17:07:08]

OnPlayerKeyStateChange(0, 4, 0)
[17:07:08] vehicle_OnPlayerKeyStateChange: 0
[17:07:08] garage_OnPlayerKeyStateChange: 0

Pa4enka
07.02.2020, 22:33
vehicle_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys == KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVehicleID(playerid) == PlayerVehicleID[playerid])
{
callcmd::engine(playerid);
return 1;
}
}
return 0;
}

Тыкнем пальцем в небо...

UPD: есть ещё вариант, что не проходит какое-то условие. Например массив PlayerVehicleID изначально хранит невалидное значение, ибо не обнуляется при входе игрока.

DeimoS
09.02.2020, 21:07
OnPlayerKeyStateChange(0, 512, 0)
[17:07:02] vehicle_OnPlayerKeyStateChange: 0
[17:07:02] garage_OnPlayerKeyStateChange: 1
[17:07:02]

Судя по логам, у тебя срабатывает только garage_OnPlayerKeyStateChange в первый раз.

Попробуй

vehicle_OnPlayerKeyStateChange(playerid, newkeys)
{
if(newkeys & KEY_SUBMISSION && GetPlayerState(playerid) == PLAYER_STATE_DRIVER)
{
if(GetPlayerVehicleID(playerid) == PlayerVehicleID[playerid])
{
callcmd::engine(playerid);
return 1;
}
}
return 0;
}

CMD:engine(playerid)
{
new Float:carhp, engine, lights, alarm, doors, bonnet, boot, objective;
if(GetPlayerVehicleID(playerid) == INVALID_VEHICLE_ID) return 1;
if(GetPlayerState(playerid) != PLAYER_STATE_DRIVER) return 1;
GetVehicleParamsEx(GetPlayerVehicleID(playerid), engine, lights, alarm, doors, bonnet, boot, objective);
GetVehicleHealth(GetPlayerVehicleID(playerid), carhp);
if(engine <= 0)
{
if(VehicleInfo[GetPlayerVehicleID(playerid)][vFuel] <= 0)
{
return 1;
}
else if(carhp <= 300.0)
{
return 1;
}
}
return 1;
}



И да


if(engine == 0)
Помимо "0" (VEHICLE_PARAMS_OFF) и "1" (VEHICLE_PARAMS_ON), у параметров автомобиля есть ещё значение "-1" (VEHICLE_PARAMS_UNSET), возвращаемое GetVehicleParamsEx когда параметр до этого не изменялся при помощи SetVehicleParamsEx. То бишь, твоя проверка внутри команды не сработает правильно Iя это уже поправил в своём коде).

+ у тебя в команде проверяется значение vehicle_OnPlayerKeyStateChange, которое задаётся только в garage_OnPlayerKeyStateChange