Всем привет! Сегодня мы напишем скрипт аренды транспорта для сервера Rage MP. В нашем случае это будет аренда скутеров. Скрипт будет полностью серверный.
Сам процесс подготовки и написания кода вы можете посмотреть в записи моего стрима. Там больше размышлений и более подробно можно отследить ход мыслей в процессе создания этого скрипта.
Для начал выберем места где можно будет взять транспорт в аренду.
На каждой из указанных точек мы поставим маркер и напишем 3Д текст "Аренда транспорта".
Чтобы при входе в маркеры аренды у нас срабатывало начало аренды мы добавим еще колшейп.
Для колшейпа мы задаем свойство isRent, чтобы его можно было отличить от других колшейпов которые могут быть на сервере.
Функция playerRentStart будет выдавать игроку арендный транспорт и делать все необходимые проверки. Например, если игрок уже имеет активную аренду, то больше транспорта мы ему не будем выдавать.
Таким образом мы выдаем игроку скутер и запоминаем это, чтобы он не мог наспавнить себе кучу транспорта.
Обычно транспорт арендуется на какой-то промежуток времени. Поэтому нам нужно будет по истечении этого промежутка удалять транспорт и информировать об этом игрока. Это можно реализовать разными способами, на стриме я более детально рассматривал их.
Мы поступим следующим образом. При начале аренды мы будем записывать в свойства арендной машины время на которое ее арендовали (количество секунд) и ИД владельца.
Почему именно так? Мы будем отслеживать аренду не по игрокам, а по арендованному транспорту. Для этого создадим массив в котором будем хранить все арендованные скутеры.
При начале аренды мы помещаем туда наш объект и потом сможет легко работать с ним.
Теперь нам осталось создать таймер в котором мы будем пробегать по всем арендованным скутерам и находить те, у которых закончилось время аренды.
Сама функция vehicleRentStop будет выполнять два действия:
1. Физически удалять транспорт.
2. Уведомлять игрока об окончании аренды и убирать у него свойство rentVehicle, чтобы он смог снова арендовать транспорт.
Здесь есть один нюанс. Ко времени окончания аренды игрок мог уже выйти с сервере. Поэтому в свойствах машины мы храним его player.id, а не ссылку на сам объект player. Т. к. проще проверить есть ли игрок онлайн по его id. Сам объект player к этому времени становится просроченным и это приводит к ошибке. Короче нам нужно проверить что игрок все еще есть на сервере и если нет, то никого уведомлять не нужно.
На этом все. Мы получили работоспособную систему аренды, которую можно развивать дальше.
Примечания:
1. За время пока закончилась аренда конечно од этим ID мог зайти другой игрок. И ему придет уведомление. Это не правильно. Возможно нужно отслеживать выход игрока с сервера и принудительно завершать аренду.
2. Аренда полностью бесплатна. Поскольку в rage mp нет стандартного api для работы с деньгами и скорее всего в каждом моде оно будет сделано по своему. Поэтому в туториале и нет упоминания денег. При необходимости это можно легко добавить. В функции playerRentStart нужно будет проверять наличие необходимой суммы и снимать деньги.
Сам процесс подготовки и написания кода вы можете посмотреть в записи моего стрима. Там больше размышлений и более подробно можно отследить ход мыслей в процессе создания этого скрипта.
Для начал выберем места где можно будет взять транспорт в аренду.
JavaScript:
const rentPoints = [
{x: -1048.4658203125, y: -2548.270263671875, z: 12.954665184020996},
{x: -1043.396728515625, y: -2539.602294921875, z: 12.954659461975098},
];
На каждой из указанных точек мы поставим маркер и напишем 3Д текст "Аренда транспорта".
JavaScript:
mp.events.add('packagesLoaded', () =>
{
rentPoints.forEach( createRentPoint );
console.log('Аренда скутеров загружена');
});
function createRentPoint(point){
const markerSize = 2;
mp.markers.new(1, point, markerSize);
mp.labels.new("Аренда скутеров", {x: point.x, y: point.y, z: point.z + 1}, {los: true, font: 1, drawDistance: 100,});
}
Чтобы при входе в маркеры аренды у нас срабатывало начало аренды мы добавим еще колшейп.
JavaScript:
function createRentPoint(point){
const markerSize = 2;
mp.markers.new(1, point, markerSize);
mp.labels.new("Аренда скутеров", {x: point.x, y: point.y, z: point.z + 1}, {los: true, font: 1, drawDistance: 100,});
const colshape = mp.colshapes.newSphere(point.x, point.y, point.z, markerSize);
colshape.isRent = true;
}
Для колшейпа мы задаем свойство isRent, чтобы его можно было отличить от других колшейпов которые могут быть на сервере.
JavaScript:
mp.events.add('playerEnterColshape', (player, colshape) => {
if( colshape.isRent){
playerRentStart(player);
}
});
Функция playerRentStart будет выдавать игроку арендный транспорт и делать все необходимые проверки. Например, если игрок уже имеет активную аренду, то больше транспорта мы ему не будем выдавать.
JavaScript:
function playerRentStart(player){
if(player.rentVehicle) return player.outputChatBox("ОШИБКА: У Вас уже есть арендованный транспорт");
const vehicle = mp.vehicles.new(mp.joaat("faggio"), player.position);
player.rentVehicle = vehicle;
}
Таким образом мы выдаем игроку скутер и запоминаем это, чтобы он не мог наспавнить себе кучу транспорта.
Обычно транспорт арендуется на какой-то промежуток времени. Поэтому нам нужно будет по истечении этого промежутка удалять транспорт и информировать об этом игрока. Это можно реализовать разными способами, на стриме я более детально рассматривал их.
Мы поступим следующим образом. При начале аренды мы будем записывать в свойства арендной машины время на которое ее арендовали (количество секунд) и ИД владельца.
JavaScript:
const rentTime = 50; // seconds
function playerRentStart(player){
// ...
vehicle.playerId = player.id;
vehicle.rentSeconds = rentTime;
}
Почему именно так? Мы будем отслеживать аренду не по игрокам, а по арендованному транспорту. Для этого создадим массив в котором будем хранить все арендованные скутеры.
JavaScript:
const rentVehicles = [];
При начале аренды мы помещаем туда наш объект и потом сможет легко работать с ним.
JavaScript:
function playerRentStart(player){
// ...
rentVehicles.push(vehicle);
}
Теперь нам осталось создать таймер в котором мы будем пробегать по всем арендованным скутерам и находить те, у которых закончилось время аренды.
JavaScript:
mp.events.add('packagesLoaded', () =>
{
// ...
setInterval( rentCheck, 1000);
});
function rentCheck(){
rentVehicles.forEach( (vehicle, index) => {
vehicle.rentSeconds = vehicle.rentSeconds - 1; // Отнимаем 1 секунду от времени аренды
if(vehicle.rentSeconds < 1){ // Если время вышло, то заканчиваем аренду
vehicleRentStop(vehicle);
rentVehicles.splice(index, 1); // удаляем из массива этот транспорт
}
});
}
Сама функция vehicleRentStop будет выполнять два действия:
1. Физически удалять транспорт.
2. Уведомлять игрока об окончании аренды и убирать у него свойство rentVehicle, чтобы он смог снова арендовать транспорт.
JavaScript:
function vehicleRentStop(vehicle){
const { playerId } = vehicle;
vehicle.destroy();
let player = mp.players.at(playerId);
player.rentVehicle = false;
player.outputChatBox("Срок аренды закончился. Транспорт доставлен на стоянку.");
}
Здесь есть один нюанс. Ко времени окончания аренды игрок мог уже выйти с сервере. Поэтому в свойствах машины мы храним его player.id, а не ссылку на сам объект player. Т. к. проще проверить есть ли игрок онлайн по его id. Сам объект player к этому времени становится просроченным и это приводит к ошибке. Короче нам нужно проверить что игрок все еще есть на сервере и если нет, то никого уведомлять не нужно.
JavaScript:
function vehicleRentStop(vehicle){
const { playerId } = vehicle;
vehicle.destroy();
if( mp.players.exists(playerId) ){
let player = mp.players.at(playerId);
player.rentVehicle = false;
player.outputChatBox("Срок аренды закончился. Транспорт доставлен на стоянку.");
}
}
На этом все. Мы получили работоспособную систему аренды, которую можно развивать дальше.
Примечания:
1. За время пока закончилась аренда конечно од этим ID мог зайти другой игрок. И ему придет уведомление. Это не правильно. Возможно нужно отслеживать выход игрока с сервера и принудительно завершать аренду.
2. Аренда полностью бесплатна. Поскольку в rage mp нет стандартного api для работы с деньгами и скорее всего в каждом моде оно будет сделано по своему. Поэтому в туториале и нет упоминания денег. При необходимости это можно легко добавить. В функции playerRentStart нужно будет проверять наличие необходимой суммы и снимать деньги.