Дальнобойщик + CEF (JS)

  • Автор темы Автор темы shevdev
  • Дата начала Дата начала

shevdev

Junior Developer
Скриптер
CОЗДАЁМ РАБОТУ ДАЛЬНОБОЙЩИКА С ИСПОЛЬЗОВАНИЕМ ВЕБ-ИНТЕРФЕЙСОВ(CEF):

Возможно некоторые функции, можно было бы объединить в одну, не спорю, но я сделал таким образом, чтобы новенькому было понятно, что за что отвечает и не пихать кучу свойств в одну. Спасибо.






Видео-урок можно найти по ссылке ниже:
(практическая часть к первому уроку)




ПОДГОТОВКА К РАЗРАБОТКЕ

1)
Клиентская должна содержать папку trucker, в ней папка cef, а так же файл index.js (внутри основной папки).
Снимок экрана (1145).png
2)Я использую мод freeroam, и изменил координаты места спавна на те, которые находятся вблизи работы.
(путь: packages/freeroam/configs/spawn_points.json)

JSON:
{
    "SpawnPoints": [
        { "x": -244, "y": 2187, "z": 130 }
  
    ]
}

3)Теперь добавим файлы в CEF-часть. По сути это была логин-панель, которую я переделал под окошко для работы :)
Хочется отметить, что на кнопку для начала я повесил событие onclick, которое вызывает в скрипте на клиентскую часть ивент.
Сделано для взаимодействия с кнопкой.

index.html: https://sourceb.in/FdtWHxqwq4
style.css: https://sourceb.in/PEWWbfNDGJ
script.js: https://sourceb.in/stnCnaOb7o

4) Для того, чтобы определить ваши координаты, можете на серверной стороне создать такую команду (взято у Rage Script):

JavaScript:
mp.events.addCommand('sp', (player) => {
    const {position} = player.vehicle
    console.log(`{ x: ${position.x}, y: ${position.y}, z: ${position.z}, heading: ${player.vehicle.rotation.z}}`)
})



СКРИПТ НА СЕРВЕРНОЙ СТОРОНЕ

1
)В packages создаем папку trucker и добавляем JS файл - index.js
2) Наша первая задача это указать координаты для маркера начала работы. Эти координаты мы будем использовать для colshape'ов и блипов так же.

Код:
const markerPos = { x: -263.631591796875, y: 2195.6708984375, z: 128.47988891601562}

3) Создаём встроенный ивент "playerReady". То есть когда игрок зайдет в игру и прогрузится, то тогда мы вызываем на клиентскую сторону пользовательский ивент "playerInitLogistWork" , а в качестве аргументов передаём наш markerPos.

Код:
mp.events.add('playerReady', (player) => {
    player.call('playerInitLogistWork', [markerPos]);
})




СКРИПТ НА СТОРОНЕ КЛИЕНТА

1
) Для начала хочу отметить, что для удобства я разбил клиентскую сторону на 3 части. Первая - переменные, вторая - функции (в моём случае это строчные функции), третья - события. Сделано это для удобства и красоты кода, чтобы если через 2 месяца обратиться к этому коду, не было раздумий, а что за что отвечает.
2) Значит давайте рассмотрим первую часть. В коде я комментариями подметил, какая переменная, за что отвечает.

JavaScript:
let colshape; // Невидимый объект для маркера начала работы.
let colshapeMarker; // Маркер начала работы.
let trackMarker; // Маркер конечного маршрута.
let trackColshape; // Невидимый объект конечного маршрута.
let showWork; // Используется для взаимодействия с CEF-частью.
let playerLocal = mp.players.local // Переменная с локальными данными игрока (для клиентской стороны)
let workStatus = 0; // Состояние работы: 0 - не работает; 1 - работает.
let muleSpawn = { x: -267.8572692871094, y: 2193.226806640625, z: 130.0386199951172, heading: -118.64833068847656} //Координаты спавна машины для работы.
let trackSpawn = { x: -230.88673400878906, y: 2081.921142578125, z: 138.77877807617188 } //Координаты спавна для маркера разгрузки.
let redColor = [255,0,0,100] //Для удобства вынес красный цвет в переменную, ибо часто используется.

3) Создав основные переменные, мы можем приступать к созданию функций, выполняющих в дальнейшем свою работу в ивентах. Очень много времени потребуется, для описания каждого действия в функции, поэтому ниже я проведу краткий экскурс по каждой, а уже подробную информацию можно найти в видео.

playerInitWork - создает маркер, колшэйп, блип при входе пользователя в игру.
beginWork - отвечает за нажатие на кнопку начала работы.
workNotify - используется как уведомление.
spawnVehiclesForWork - спавн рабочего автомобиля.
startColshape - вывод интерфейса.
setCheckPoint - установка чекпоинта в случае начала работы.
vehicleCheck - проверка на наличие игрока в машине(для того чтобы он не смог добежать пешком)
clearTrack - удаляет маркер, колшэйп и блип.
startTrackShape - окончание работы.


JavaScript:
const playerInitWork = (marker) => {
    colshapeSphere = mp.colshapes.newSphere(marker.x, marker.y ,marker.z+1, 2)
    colshapeMarker = mp.markers.new(1, [marker.x+1, marker.y, marker.z+1], 1, {color: redColor});
    mp.peds.new(
        mp.game.joaat('cs_dreyfuss'),
        [marker.x, marker.y ,marker.z+2, 1],
        260.0,
        playerLocal.dimension
    );
}
const beginWork = () => {
    showWork.execute("mp.invoke('focus', false)")
    showWork.active = false
    mp.game.graphics.stopScreenEffect("ChopVision")
    mp.gui.chat.activate(true)
}
const workNotify = (msgText) => {
    mp.game.ui.setNotificationTextEntry('STRING');
    mp.game.ui.setNotificationMessage('CHAR_RON', 'CHAR_RON', false, 2, 'Новое сообщение', msgText);
};
const spawnVehiclesForWork = (carName, carSpawn) => {
        mp.vehicles.new(mp.game.joaat(carName), carSpawn, {heading: carSpawn.heading})
}
const startColshape = () => {
    showWork = mp.browsers.new('package://trucker/cef/index.html')
    showWork.execute("mp.invoke('focus', true)")
    mp.gui.chat.activate(false)
    mp.game.graphics.startScreenEffect("ChopVision", 0, true)
}

const setCheckPoint = () => {
    trackColshape = mp.colshapes.newSphere(trackSpawn.x, trackSpawn.y, trackSpawn.z, 3)
    trackMarker = mp.markers.new(1, [trackSpawn.x, trackSpawn.y, trackSpawn.z-2], 3, {color: redColor, visible: true});
    trackBlip = mp.blips.new(431, [trackSpawn.x, trackSpawn.y, trackSpawn.z], {shortRange: false});
    trackBlip.setRoute(true);
}
const vehicleCheck = () => {
    if(!playerLocal.vehicle) {
        workNotify('Вы не можете доставить груз на ногах!')
        return false;
    }
    return true;
}
const clearTrack = () => {
    trackColshape.destroy();
    trackMarker.destroy();
    trackBlip.destroy()
}
const startTrackShape = () => {
    if(!vehicleCheck()) return mp.gui.chat.push("Вы должны быть в транспорте.")
    clearTrack()
    workStatus = 0
}

4) В завершении события. Опять же подробную информацию о каждой строчке вы найдете в видео. Я же кратко пробегусь по каждому из них.


playerInitLogistWork - событие, отвечающие за установку маркеров и т д.
playerEnterColshape - событие, проверяет встал ли игрок на колшэйп.
beginWork - событие, сверяющие не начал ли игрок работу.
playerEnterVehicle - событие, отвечающие за то, что если игрок в машине, то ему устанавливается рабочий маршрут.


JavaScript:
mp.events.add('playerInitLogistWork', (markerPos) => {
    playerInitWork(markerPos)
}) 
/////////////////////////////////////////////////////////////
mp.events.add('playerEnterColshape', (colshape) => {
    if( colshape == colshapeSphere ) {
        startColshape()
    }
    if(colshape == trackColshape) {
        startTrackShape()
        workNotify('Ты доставил груз. Возвращайся!')
    }
}) 
//////////////////////////////////////////////////////////////
mp.events.add('beginWork', () => {
    if(workStatus == 1 ) {
        beginWork()
        workNotify('Вы уже начали работу!')
    }
    else {
        beginWork()
        spawnVehiclesForWork('mule3', muleSpawn)
        workNotify('Начинайте развозить товары!')
        workStatus = 1
    }
}) 
//////////////////////////////////////////////////////////////
mp.events.add('playerEnterVehicle', () => {
    if(workStatus = 1) {
        setCheckPoint()
    }
})




ДОМАШНЕЕ ЗАДАНИЕ ПО УРОКУ

1
) Добавить больше точек маршрута.
2) Создать проверку на то, в каком автомобиле находится рабочий.
3) Так же можно добавить в CEF кнопку завершения работы досрочно.




СКАЧАТЬ РАБОТУ ДАЛЬНОБОЙЩИКА С CEF (АРХИВ):
P.S Если вы нажали на кнопку нажатия работы и у вас далее ничего не произошло - релогнитесь.

https://disk.yandex.ru/d/glZOUjoeDmoEsA




Очень интересно, что вы думаете по этому уроку. Вдохновлен был видеороликом Rage Script, по работе дальнобойщика, решил написать свой вариант с использованием CEF. Код скорее всего можно и укоротить, чтобы он был меньше, но я старался все максимально подробно описать, чтобы новеньким было понятно. Надеюсь получилось, спасибо :)
 
Последнее редактирование:
привет, очень классный код. было бы еще лучше получить готовые файлы packages и т.д в архиве, для тестов
 
Круто, спасибо что поделился и так подробно расписал! Ждем видео и исходники :) Чуть позже гляну подробнее, еще на работе.
 
Немного нашёл несущественных недоработок но всё же.
1. Если ты вступил на марке, кроме начать работы ты никак не сможешь выбраться (крепостной труд получается XD)
2. После выполнение задание и возвращение назад на то место где был транспорт при повторном взятие работы машины спавнится об другую машину (хотелось бы чтобы вы помогли как убрать предыдущий транспорт когда ты из него вылез)

update: когда садишься в другой транспорт работа начинается автоматически
 
Последнее редактирование:
Немного нашёл несущественных недоработок но всё же.
1. Если ты вступил на марке, кроме начать работы ты никак не сможешь выбраться (крепостной труд получается XD)
2. После выполнение задание и возвращение назад на то место где был транспорт при повторном взятие работы машины спавнится об другую машину (хотелось бы чтобы вы помогли как убрать предыдущий транспорт когда ты из него вылез)

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

А во-вторых, возник вопрос по теме дальнобойщиков. Большинство не запаривается и делает дальнобой на грузовиках без прицепа.
Но игра на рейдже позволяет взять грузовик (голову) и легко зацепить прицеп.
Но у этой возможности есть минус, при слишком крутом повороте или других ситуациях прицеп слетает с фуры и нужно снова делать сцепку. Уверен, что отыгрывая дальнобойщиков игрокам будет не комфортно. Это беда любого сервера. Не прогруз и уже другой игрок влетает в тебя на скорости и прицеп слетает. И возможно за рейс таких ситуаций будет много и у игроков будет сплошной негатив.
Возможно ли после сцепки с прицепом блокировать возможность слёта и отцепки?
Кажется такое реализовано на Smotra RPG. Но я могу ошибаться.
В любом случае буду признателен любым советам, предложениям и просто идеям)
 
Во-первых, спасибо за ваш труд и время.

А во-вторых, возник вопрос по теме дальнобойщиков. Большинство не запаривается и делает дальнобой на грузовиках без прицепа.
Но игра на рейдже позволяет взять грузовик (голову) и легко зацепить прицеп.
Но у этой возможности есть минус, при слишком крутом повороте или других ситуациях прицеп слетает с фуры и нужно снова делать сцепку. Уверен, что отыгрывая дальнобойщиков игрокам будет не комфортно. Это беда любого сервера. Не прогруз и уже другой игрок влетает в тебя на скорости и прицеп слетает. И возможно за рейс таких ситуаций будет много и у игроков будет сплошной негатив.
Возможно ли после сцепки с прицепом блокировать возможность слёта и отцепки?
Кажется такое реализовано на Smotra RPG. Но я могу ошибаться.
В любом случае буду признателен любым советам, предложениям и просто идеям)
Cинхронизацию надо писать, что и сделали Смотра)
 
Во-первых, спасибо за ваш труд и время.

А во-вторых, возник вопрос по теме дальнобойщиков. Большинство не запаривается и делает дальнобой на грузовиках без прицепа.
Но игра на рейдже позволяет взять грузовик (голову) и легко зацепить прицеп.
Но у этой возможности есть минус, при слишком крутом повороте или других ситуациях прицеп слетает с фуры и нужно снова делать сцепку. Уверен, что отыгрывая дальнобойщиков игрокам будет не комфортно. Это беда любого сервера. Не прогруз и уже другой игрок влетает в тебя на скорости и прицеп слетает. И возможно за рейс таких ситуаций будет много и у игроков будет сплошной негатив.
Возможно ли после сцепки с прицепом блокировать возможность слёта и отцепки?
Кажется такое реализовано на Smotra RPG. Но я могу ошибаться.
В любом случае буду признателен любым советам, предложениям и просто идеям)
Там глобальная проблема с синхронизацией трейлеров. Чтобы оно адекватно работало, пока что нужно тулить свою синхронизацию.
У нас в дискорда в сниппетах есть пример реализации синхры трейлеров от Голема.
 
Там глобальная проблема с синхронизацией трейлеров. Чтобы оно адекватно работало, пока что нужно тулить свою синхронизацию.
У нас в дискорда в сниппетах есть пример реализации синхры трейлеров от Голема.
Да, я встречал в сети реализацию Голема.
В итоге игра не стоит свечь?
 
Ребята, в процессе возник вопрос. У рейджа в вики есть несколько видов трейлеров(прицепов). Для легкового и грузового транспорта. Оба без проблем можно зацепить пикапом или грузовиком, но вот как функционально можно отстегнуть прицеп? К примеру через нажатие G на прицепе.
А так же второй вопрос, есть прицеп для перевозки легковушек двух уровневый. Есть даже на гта5модс моды для 2х функций(откинуть балки для заезда авто и вверх/вниз второго яруса прицепа).
Перелазил ужё все, но так и не нашёл ответа.
 
На сколько я помню в рейжде нет таких функций. Но можно порыться в нативках, возможно что-то из этого удастся найти.
 
Назад
Верх