• Просьба не публиковать сообщения с предложениями продажи модов или сборок!

    Мы против использования и перепродажи слитых модов и переделок на их основе. Остальное также сложно верифицировать, поэтому в целом пока что запрещаем эту тему на сайте.

[1.1] Доступ к транспортному средству

SlowSuicide

Middle Developer
Скриптер
Сообщения
64
Доброго времени суток уважаемые форумчане!
Client-Side: JS;
Server-Side: C#;

Стоит следующая задача:
Требуется блокировать дверные ручки транспортного средства если игрок не входит в определённую группу/фракцию
и соответственно разблокировать ручки ТС если входит в группу/фракцию.

Решения создания ивента на клиентской стороне что на JS, что на C# версии 1.1 не работает, а именно:

Events.OnPlayerStartEnterVehicle += OnPlayerStartEnterVehicle;
public void OnPlayerStartEnterVehicle(RAGE.Elements.Vehicle vehicle, int seatId, RAGE.Events.CancelEventArgs cancel)
{
if (seatId == -1)
{
RAGE.Chat.Output("You started to get in the driver's seat");
}
else
{
RAGE.Chat.Output("You started to get in a passenger seat");
}
}
// The player is not emmited client-side assuming it's you
function playerStartEnterVehicleHandler(vehicle, seat) {
const vehicleID = vehicle.id;

mp.game.graphics.notify(`You started to get into the car ID: ${vehicleID}. Seat: ${seat}`);
}

mp.events.add("playerStartEnterVehicle", playerStartEnterVehicleHandler);
wiki.rage.mp
На серверной части альтернативы не нашёл или то, что пытался найти - оказалось так же не рабочим (Серверная JS часть не актуальна, онли акула)

Может среди вас имеются те, кто знают как решить данную задачу?
 
Решение
Вот, работает как надо.

Клиент
JavaScript:
let prevSeat;
mp.events.add('render', () => {
    const seat = mp.players.local.getSeatIsTryingToEnter();
    if(seat != prevSeat){
        prevSeat = seat;
        if(seat == -1) mp.events.callRemote('clientStartVehicleEnter', seat );
    }
});

Сервер
JavaScript:
mp.events.add("clientStartVehicleEnter", (player) => {
    player.outputChatBox('You start entering vehicle');
});

Рендер конечно не самое лучшее место, возможно будет достаточно таймера с небольшим интервалом.
Это решение работает. Переделанное решение для того чтобы ивент не делал кучу колбэков и вызывал метод на сервере 1 раз:

let prevSeat;
mp.events.add('render', () => {
const seat =...
Там возможно есть бага на клиентской части. Я встречал упоминание об этом во фрироме. Там чел обрабатывал событие на сервере и отправлял call на клиент.
Сервер
JavaScript:
/* !!! REMOVE AFTER FIX (TRIGGERED FROM SERVER) !!! */
mp.events.add('playerEnteredVehicle', (player) => {
    if (player.vehicle && player.seat === 0 || player.seat === 255)
        player.call('playerEnteredVehicle');
});
/* */
Клиент
JavaScript:
    // Show vehicle buttons, when player enters vehicle (triggered from server, will be fixed on the client-side).
    mp.events.add('playerEnteredVehicle', () => {
        menu.execute('$("#vehicle_buttons").fadeIn(250);');
    });

Но хз на сколько оно актуально, учитывая что в фрироме связанный с этим функционал не работает как требуется.

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

возможно надо устанавливать на транспорт свойство "невзламываемый" и может будет работать нормально, но это я не пробовал пока что
 
Там возможно есть бага на клиентской части. Я встречал упоминание об этом во фрироме. Там чел обрабатывал событие на сервере и отправлял call на клиент.
Сервер
JavaScript:
/* !!! REMOVE AFTER FIX (TRIGGERED FROM SERVER) !!! */
mp.events.add('playerEnteredVehicle', (player) => {
    if (player.vehicle && player.seat === 0 || player.seat === 255)
        player.call('playerEnteredVehicle');
});
/* */
Клиент
JavaScript:
    // Show vehicle buttons, when player enters vehicle (triggered from server, will be fixed on the client-side).
    mp.events.add('playerEnteredVehicle', () => {
        menu.execute('$("#vehicle_buttons").fadeIn(250);');
    });

Но хз на сколько оно актуально, учитывая что в фрироме связанный с этим функционал не работает как требуется.

Сейчас на работе, вечером постараюсь протестить.
Ивент playerEnteredVehicle на сколько могу знать срабатывает уже после того, как игрок сел в транспортное средство. То есть, если я по умолчанию изначально сделаю все двери закрытыми - он не сможет сесть в авто потому что ивент не сработает
 
Я потратил на данную проблему большое количество времени, мне удалось придумать только единственный костыль используя ивент
playerEnteredVehicle (Но опять же это костыль, в идеализацию это не входило но пришлось так сделать).
С помощью клиентской части благодаря функции игрока localplayer.setConfigFlag(flagId, state) благодаря флагу №429 (PED_FLAG_STOP_ENGINE_TURNING) можно запретить заводить двигатель.

То есть по умолчанию всем игрокам запрещено заводить двигатель, когда игрок сел в ТС - срабатывает ивент который делает проверку и в случае чего меняет значение флага.
Далее, когда игрок выходит из ТС - срабатывает ивент playerExitVehicle, который вновь запрещает игроку заводить двигатель
 
Я не считаю проблему решённой так как приоритетно была задача блокировать дверные ручки, но если кому нужно - способ сообщением ранее является рабочим для блокировки двигателя игроку
 
А что если, когда спавнишь фракционую машину, то по умолчанию ее закрывать и открывать разрешить только членам фракции с помощью команды?
 
А что если, когда спавнишь фракционую машину, то по умолчанию ее закрывать и открывать разрешить только членам фракции с помощью команды?
скажем так, мой режим предполагает динамичную игру в которой это бы считалось действием траты времени, можно рассмотреть конечно бинд действия на кнопку, но опять же это придётся нажимать на одну кнопку (кнопку бинда), затем нажатием на F садиться в машину (игроки могут попросту запутаться в итоговом счёте), поэтому в данном случае костыль с глушением двигателя будет решением получше текущего предположения
 
Существует ли ивент, который будет срабатывать когда игрок подходит к машине?
 
Я потратил на данную проблему большое количество времени, мне удалось придумать только единственный костыль используя ивент
playerEnteredVehicle (Но опять же это костыль, в идеализацию это не входило но пришлось так сделать).
С помощью клиентской части благодаря функции игрока localplayer.setConfigFlag(flagId, state) благодаря флагу №429 (PED_FLAG_STOP_ENGINE_TURNING) можно запретить заводить двигатель.

То есть по умолчанию всем игрокам запрещено заводить двигатель, когда игрок сел в ТС - срабатывает ивент который делает проверку и в случае чего меняет значение флага.
Далее, когда игрок выходит из ТС - срабатывает ивент playerExitVehicle, который вновь запрещает игроку заводить двигатель
А что если просто выбрасывать его из машины? https://wiki.gtanet.work/index.php?title=WarpPlayerOutOfVehicle

Существует ли ивент, который будет срабатывать когда игрок подходит к машине?
Может колшейп как то получится приаттачить к машине?
 
А что если просто выбрасывать его из машины? https://wiki.gtanet.work/index.php?title=WarpPlayerOutOfVehicle


Может колшейп как то получится приаттачить к машине?
К каждой машине колшейп - нагрузка на сервер, потому что нужно делать столько колшейпов, сколько и машин.
Решение с двигателем тоже оказалось проблемным при тестировании с игроками - если сразу сесть и поехать - машина поедет ахах, если сесть и поехать через секунду или две - то не поедет.
Выбрасывать из машины: мне в будущем нужно сделать функционал при котором можно будет через CEF взламывать машину, поэтому нужно как-нибудь додумать мыслю по поводу определения "Стоит ли игрок рядом с ТС" и "Какая это ТС (для получения ID машины)"
 
Вот, работает как надо.

Клиент
JavaScript:
let prevSeat;
mp.events.add('render', () => {
    const seat = mp.players.local.getSeatIsTryingToEnter();
    if(seat != prevSeat){
        prevSeat = seat;
        if(seat == -1) mp.events.callRemote('clientStartVehicleEnter', seat );
    }
});

Сервер
JavaScript:
mp.events.add("clientStartVehicleEnter", (player) => {
    player.outputChatBox('You start entering vehicle');
});

Рендер конечно не самое лучшее место, возможно будет достаточно таймера с небольшим интервалом.
 
В данном случае вопрос, сможет ли он передать ID транспорта на сервер, пока не сел в ТС?
 
Вот, работает как надо.

Клиент
JavaScript:
let prevSeat;
mp.events.add('render', () => {
    const seat = mp.players.local.getSeatIsTryingToEnter();
    if(seat != prevSeat){
        prevSeat = seat;
        if(seat == -1) mp.events.callRemote('clientStartVehicleEnter', seat );
    }
});

Сервер
JavaScript:
mp.events.add("clientStartVehicleEnter", (player) => {
    player.outputChatBox('You start entering vehicle');
});

Рендер конечно не самое лучшее место, возможно будет достаточно таймера с небольшим интервалом.
Это решение работает. Переделанное решение для того чтобы ивент не делал кучу колбэков и вызывал метод на сервере 1 раз:

let prevSeat;
mp.events.add('render', () => {
const seat = mp.players.local.getSeatIsTryingToEnter();
if(seat != prevSeat){
prevSeat = seat;
if(seat == -1)
{
const vehHandle = mp.players.local.getVehicleIsTryingToEnter();
if (vehHandle)
{
const veh = mp.vehicles.atHandle(vehHandle);
if (veh)
{
mp.gui.chat.push(`You are trying to enter vehicle model: ${veh.model}, with remote id: ${veh.remoteId}.`); //тест сообщение в чат
mp.events.callRemote('OnPlayerEnterVehicleHandler', veh.remoteId); //Вызываю метод OnPlayerEnterVehicleHandler на сервере и передаю ид ТС
}
}
}
}
});
 
Решение
Соответственно на серверной части у меня заранее имеется подготовленный список авто, я смотрю - есть ли ID данного авто в списке - если есть и игрок не состоит в фракции - я блокирую двери vehicle.locked = true (C#)
 
Супер (y) Это конечно тоже костыль, но лучше пока не придумали. Когда пофиксят серверный event можно будет легко перейти на него.
 
Назад
Верх