Вопросы

Здравствуйте. Делаю фулл рп мод с нуля. Не подскажете как сделать автоматическое удаление незанятого транспорта с сервера с сообщением «Весь незанятый транспорт был автоматически удалён с сервера»?

Поделиться сообщением


Ссылка на сообщение

10 ответов на этот вопрос

  • 1

@Tookie Johnson,

 

Спойлер

/**
    @brief Функция проверка занятости транспортного средства
    @retval Возвращает true, если транспортное средство vehicleID занято, иначе – false
*/

stock bool:IsVehicleOccupied(vehicleid) {

    for (new i = 0; i < MAX_PLAYERS; i++) {
        if (!IsPlayerConnected(i)) {
            continue;
        }

        new const vehicleID = GetPlayerVehicleID(playerid);
        if (vehicleID == INVALID_VEHICLE_ID) {
            continue;
        }

        return true;
    }

    return false;
}

#if !defined IsValidVehicle
    native IsValidVehicle(vehicleid);
#endif

stock DestroyUnoccupiedVehicles() {

    for (new vehicleID = 0; vehicleID < MAX_VEHICLES; vehicleID++) {
        if (!IsValidVehicle(vehicleID)) { // если транспортное средство не существует
            continue// идем далее
        }

        if (IsVehicleOccupied(vehicleID)) { // если транспортное средство занято
            continue// идем далее
        }
        
        DestroyVehicle(vehicleID); // уничтожаем незанятое транспортное средство
    }
}

 

 

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee, не вижу смысла расписывать каждое условие, если его можно совместить в одно. Так же, не вижу смысла приравнивать новую переменную к нулю, когда она и так равна нулю. В целом, оба варианта рабочие.

stock DestroyUnoccupiedVehicles() {
    for (new vehicleID = 1; vehicleID <= GetVehiclePoolSize(); vehicleID++) {
        if(IsValidVehicle(vehicleID) && !IsVehicleOccupied(vehicleID)) // если транспортное средство не существует и не занято
            DestroyVehicle(vehicleID); // уничтожаем незанятое транспортное средство
        else
            continue;
    }
}

Да и в цикле вместо MAX_PLAYERS будет разумнее использовать функцию GetPlayerPoolSize:

stock bool:IsVehicleOccupied(vehicleid) {
    for (new i; i <= GetPlayerPoolSize(); i++) {
        if(!IsPlayerConnected(i))
            continue;

        new const vehicleID = GetPlayerVehicleID(playerid);
        if(vehicleID == INVALID_VEHICLE_ID)
            continue;

        return true;
    }
    return false;
}

 

P.S: обновил код функции DestroyUnoccupiedVehicles.

Отредактировано пользователем 𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧.

Поделиться сообщением


Ссылка на сообщение
  • 0

Кажется, что IsVehicleOccupied не совсем правильно написана, она не использует переданный ей аргумент vehicleid

Вроде так правильно будет 

stock bool:IsVehicleOccupied(vehicleId) {
    for (new i; i <= GetPlayerPoolSize(); i++) {
        if(!IsPlayerConnected(i))
            continue;

        new const playerVehicleId = GetPlayerVehicleID(playerid);
        if(playerVehicleId == INVALID_VEHICLE_ID || playerVehicleId != vehicleId)
            continue;

        return true;
    }
    return false;
}

 

Поделиться сообщением


Ссылка на сообщение
  • 0

@DEST, двоякая ситуация. Тут либо делать проверку на одно авто с передаваемым параметром, либо делать на все сразу. Если учитывать задачу, для которой она требуется, тогда лучше сделать функцию с передаваемым параметром. К тому же, функция неверна.

Более оптимизированный вариант. В данном варианте избегаем двух проверок: 1. IsPlayerInAnyVehicle; 2. GetPlayerVehicleID;

stock bool:IsVehicleOccupied(vehicleid) {
    for(new i; i <= GetPlayerPoolSize(); i++) {
        if(!IsPlayerConnected(i))
            continue;

        if(vehicleid == INVALID_VEHICLE_ID)
            continue;

        if(IsPlayerInVehicle(i, vehicleid))
            continue;
        
        return true;
    }
    return false;
}

 

Отредактировано пользователем 𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧.

Поделиться сообщением


Ссылка на сообщение
  • 0
1 минуту назад, Cawfee сказал:

Вот только к стилю не хватало придираться.

Я не придираюсь к твоему стилю. Вопрос в удобстве и в кол-ве используемых строк. Как твой, так и мой вариант будет рабочим. Я повидал достаточно кода, чтобы не судить других за стиль написания. Не знаю, почему ты принимаешь мои слова на свой счёт.

Поделиться сообщением


Ссылка на сообщение
  • 0
1 час назад, 𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧. сказал:

Если учитывать задачу, для которой она требуется, тогда лучше сделать функцию с передаваемым параметром

Тут не соглашусь, все же функция не должна зависеть от места вызова. Т.е. я должен иметь возможность воспользоваться этой функцией из любого места в проекте, и не должно быть разницы в ее работе. Не всегда, конечно, так получается, но к этому определенно нужно стремиться. 

 

По названию этой функции можно сказать, что она возвращает true, если авто занято кем-либо, и false, если нет. Не понял что ты поменял, функция IsPlayerInVehicle и GetPlayerVehicleID имеют скорее всего одинаковую скорость работы, т.к. обращаются к одним и тем же данным. Просто одна возвращает bool, а другая - ID машины. 

 

59 минут назад, 𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧. сказал:

Не знаю, почему ты принимаешь мои слова на свой счёт

Так ты в начале сообщения его тегнул, на чей счет это можно еще принять? :bk:

Поделиться сообщением


Ссылка на сообщение
  • 0

Ребят, спасибо вам за помощь. Сейчас буду пробовать ваши коды. Как остановлюсь на рабочем - напишу и закроете тему.

Поделиться сообщением


Ссылка на сообщение
  • 0

@Cawfee, можете закрывать тему.

Поделиться сообщением


Ссылка на сообщение
  • -1

@𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧.,

 

4 часа назад, 𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧. сказал:

не вижу смысла расписывать каждое условие, если его можно совместить в одно

Вот только к стилю не хватало придираться. Всегда пишу в таком стиле. Далее фрагмент из рабочего проекта, чтоб уж совсем добить твои глаза.

 

Спойлер

if (false
    || (true // если мы в канале A и пришло сообщение от канала A
        && (pMessage->dscrptr == 0xA400)
        && (gChannel == CHANNEL_A)
    )
    || (true // или если мы в канале B и пришло сообщение от канала B
        && (pMessage->dscrptr == 0xB400)
        && (gChannel == CHANNEL_B)
    )
) { // тогда отрабатываем это сообщение

    if (pMessage->length != 8) { // если устаревшая версия сообщения
        return// игнорируем его
    }

    const auto param = pMessage->body[0];
    if (false
       || (param == /* неважно */// если это параметр ...
       || (param == /* неважно */// или параметр ...
       || (param == /* неважно /*) // или параметр ...
       || (param == /* неважно */// или параметр ...
    ) {
        gSyncConfiguration = true// обновим конфигурацию для перерасчета параметров движения
        sendCommandViaUart(COMMAND_UPDATE_CONFIG); // уведомляем другой процессор о необходимости перерасчета параметров
    }

    onParamReceived(pMessage->body[0], pMessage->body[1]); // обрабатываем пришедшее сообщение
}

 

 

4 часа назад, 𝙡𝙖𝙨𝙩 𝙚𝙢𝙥𝙚𝙧𝙤𝙧. сказал:

Так же, не вижу смысла приравнивать новую переменную к нулю, когда она и так равна нулю

Жертва языков с автоматическим управлением памятью... С меня не будет от того, что лишний раз явно инициализирую переменную.

Поделиться сообщением


Ссылка на сообщение

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!


Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.


Войти
  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

  • Похожий контент

    • Sten Developer
      От Sten Developer
      Объясню всю ситуацию, пишу систему смерти игрока но она не работает. Решил по приколу написать туда обычный вывод текста SCM(playerid, COLOR_RED, "Вы умерли");
      Но однако после смерти текст не выводиться. Не работает абсолютно все. Кто знает как решить эту проблему?