• Из-за обновления GTA 5 (был добавлен новый патч) может временно не работать вход в RAGE Multiplayer.

    Ошибка: Ваша версия Grand Theft Auto V не поддерживается RAGE Multiplayer.
    ERROR: Your game version is not supported by RAGE Multiplayer.

    Данная ошибка говорит о том, что GTA V обновилась до новой версии (GTA Online тоже). Вам необходимо обновить саму игру в главном меню вашего приложения (Steam / Epic Games / Rockstar Games).
    Если после этого RAGE:MP все равно не работает - вам нужно дождаться выхода патча для самого мультиплеера (обычно это занимает от нескольких часов до нескольких дней).

    Новости и апдейты Rockstar Games - https://www.rockstargames.com/newswire/
    Статус всех служб для Rockstar Games Launcher и поддерживаемых игр: https://support.rockstargames.com/ru/servicestatus


    Grand Theft Auto 5 (+ GTA Online) последний раз были обновлены:

Вопрос Выбор ближайшего игрока

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Приветствую, у меня появился вопрос, за ранее, не судите строго. Мне нужно выбрать ближайшего игрока, накидал примерно такой код:

JavaScript:
mp.events.add('entityStreamIn', (entity) => {
    if (entity.type == "player") {
        var playerPos = mp.players.local.position;
        var playerDist = mp.game.gameplay.getDistanceBetweenCoords(playerPos.x, playerPos.y, playerPos.z, player.position.x, player.position.y, player.position.z, true)

        if (playerDist > 15) return
        // здесь мне нужно выбрать ближайшего игрока
    }
});

Не могу понять, как мне выбрать ближайшего игрока.
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
Глупо делать это в entityStreamIn, потому как этот ивент отрабатывает в момент, когда игрок только-только появляется у тебя в зоне стрима.

За минуту накидал функцию, которая вернёт при использовании ближайшего к человеку игрока.
Вполне вероятно, что это возможно улучшить, не работаю с JS'ом.
JavaScript:
function GetClosestPlayer()
{
    let closestPlayer = null;
    let closestDist;
    let localPlayerPosition = mp.players.local.position;
    let targetPlayerPosition;
    let dist;
    
    mp.players.forEachInStreamRange((entity) =>
    {
        if (!entity || !mp.players.exists(entity)) return;
        
        targetPlayerPosition = entity.position;
        dist = mp.game.gameplay.getDistanceBetweenCoords(localPlayerPosition.x, localPlayerPosition.y, localPlayerPosition.z, targetPlayerPosition.x, targetPlayerPosition.y, targetPlayerPosition.z, true);
        if (dist > 15) return;
        if (closestPlayer == null)
        {
            closestPlayer = entity;
            closestDist = dist;
            return;
        }
        if (closestDist < dist) return;

        closestDist = dist;
        closestPlayer = entity;
    });
    return closestPlayer;
}
 
Последнее редактирование:

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Глупо делать это в entityStreamIn, потому как этот ивент отрабатывает в момент, когда игрок только-только появляется у тебя в зоне стрима.

За минуту накидал функцию, которая вернёт при использовании ближайшего к человеку игрока.
Вполне вероятно, что это возможно улучшить, не работаю с JS'ом.
JavaScript:
function GetClosestPlayer()
{
    let closestPlayer = null;
    let closestDist;
    let localPlayerPosition = mp.players.local.position;
    let targetPlayerPosition;
    let dist;
    mp.players.forEachInStreamRange((entity) =>
    {
        if (!entity || !mp.players.exists(entity)) return;
       
        targetPlayerPosition = entity.position;
        dist = mp.game.gameplay.getDistanceBetweenCoords(localPlayerPosition.x, localPlayerPosition.y, localPlayerPosition.z, targetPlayerPosition.x, targetPlayerPosition.y, targetPlayerPosition.z, true);
        if (closestPlayer == null)
        {
            closestPlayer = entity;
            closestDist = dist;
            return;
        }
       
        if (closestDist < dist) return;
       
        closestDist = dist;
        closestPlayer = entity;
    });
    return closestPlayer;
}
То есть лучше использовать рендер?
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
То есть лучше использовать рендер?
Нет, рендер будет еще хуже, потому что рендер отрабатывает каждый кадр клиента.
Если у игрока 60 FPS, то 60 раз в секунду отработает рендер, тебе это не надо.
Зависит от задачи, которую ты хочешь выполнить.

Если тебе просто нужно раз в какое-то время находить, то создай интервал, например.
JavaScript:
setInterval(() =>
{
    // code
}, 1000) // 1000ms = 1s

Если тебе нужно будет остановить этот таймер в какой-то момент, то при инициализации ты можешь хранить его айди и очистить в нужный момент:
JavaScript:
let intervalId;
intervalId = setInterval(() =>
{
    // code
}, 1000);

clearInterval(intervalId);
intervalId = null;
 
Последнее редактирование:

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Нет, рендер будет еще хуже, потому что рендер отрабатывает каждый кадр клиента.
Если у игрока 60 FPS, то 60 раз в секунду отработает рендер, тебе это не надо.
Зависит от задачи, которую ты хочешь выполнить.

Если тебе просто нужно раз в какое-то время находить, то создай интервал, например.


JavaScript:
setInterval(() =>
{
    // code
}, 1000) // 1000ms = 1s
Я делаю взаимодействие персонажей, поэтому и выбрал entityStreamIn
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
Я делаю взаимодействие персонажей, поэтому и выбрал entityStreamIn
В таком случае setInterval тебе подойдёт больше, чем entityStreamIn и render.
Регулируй таймер обновления в миллисекундах внутри, но не делай слишком маленьким за ненадобностью.
 

X-Clusiv

Модератор
Команда форума
Moderator
BackEnd developer
4 Окт 2020
708
319
161
30
Для реализации взаимодействия можно использовать немного другой подход. А именно raycasting -> https://wiki.rage.mp/index.php?title=Raycasting::testPointToPoint
Принцип прост, основан на луче. Если лучу препятствует другой игрок, взаимодействуем с ним.
 

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Для реализации взаимодействия можно использовать немного другой подход. А именно raycasting -> https://wiki.rage.mp/index.php?title=Raycasting::testPointToPoint
Принцип прост, основан на луче. Если лучу препятствует другой игрок, взаимодействуем с ним.
Окей, я попробовал сделать так, но он не может найти координаты сущности, сейчас пробую определять машину, однако, все еще выдает ошибку 'posiition', как будто он просто не знает что это

JavaScript:
mp.events.add('render', (entity) => {

    const startPosition = mp.players.local.getBoneCoords(12844, 0.5, 0, 0);
    const endPosition = entity.position;

    const hitData = mp.raycasting.testPointToPoint(startPosition, endPosition);
    if (!hitData) {
        if (entity.type == 'vehicle') {
            mp.game.graphics.drawLine(startPosition.x, startPosition.y, startPosition.z, endPosition.x, endPosition.y, endPosition.z, 255, 255, 255, 255);
        } // Is in line of sight
    } else {
        if (entity.type == 'vehicle') {
            mp.game.graphics.drawLine(startPosition.x, startPosition.y, startPosition.z, endPosition.x, endPosition.y, endPosition.z, 255, 0, 0, 255); // Is NOT in line of sight
        }
    }

});
 

mippoosedev

Гуру
BackEnd developer
2 Мар 2021
292
127
100
Для реализации взаимодействия можно использовать немного другой подход. А именно raycasting -> https://wiki.rage.mp/index.php?title=Raycasting::testPointToPoint
Принцип прост, основан на луче. Если лучу препятствует другой игрок, взаимодействуем с ним.
Это худшее, что можно сделать. Raycasting это очень затратная вещь в целом, а в рейдже так тем более) Советую более лаконичный подход ^_^

p.s использую так же в рендере
p.s.s closest = просто рандомный объект
p.s.s.s циферка 2 в фориче - расстояние, на котором проверять игроков, можно занести в константу, но я профи в говнокоде, поэтому сделал так

JavaScript:
mp.players.forEachInRange(mp.players.local.position, 2, (player) => {
        if ((player && player.doesExist()) === false) return
        if (player.remoteId === mp.players.local.remoteId) return
        let pos = mp.game.graphics.getScreenCoordFromWorldCoord(player.position.x, player.position.y, player.position.z)
        if (pos.result !== false)
        {
            let screenSize = mp.game.graphics.getActiveScreenResolution()
            let dist = Math.sqrt(Math.pow(pos.screenX * screenSize.x - screenSize.x / 2, 2) + Math.pow(pos.screenY * screenSize.y - screenSize.y / 2, 2))
            if (dist < closest.dist)
            {
                closest.dist = dist
                closest.id = player.remoteId
                closest.type = TYPES.PLAYER.name
                closest.menuId = TYPES.PLAYER.menuId
                closest.name = player.name
            }
        }
    })
 
Реакции: Aiden

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Хорошо, мне, в принципе, для своего понимания, требуется понять, как сравнить все сущности в нужном диапазоне, и понять какая ближе всех, только этот отрывок кода, потому что я правда не могу понять

грубо говоря я ищу что-то по типу:

если(есть игрок и все сущности в диапазоне то мы выбираем самую ближнюю)
 
Последнее редактирование:

mippoosedev

Гуру
BackEnd developer
2 Мар 2021
292
127
100
Хорошо, мне, в принципе, для своего понимания, требуется понять, как сравнить все сущности в нужном диапазоне, и понять какая ближе всех, только этот отрывок кода, потому что я правда не могу понять

грубо говоря я ищу что-то по типу:

если(есть игрок и все сущности в диапазоне то мы выбираем самую ближнюю)
Выше такой алгоритм и используется, находя ближайший к центру экрана в радиусе 2 метров
 

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Прошу прощения, попробовал сделать что-то свое, но финальную проверку не могу доделать, вот что накалякал:
JavaScript:
mp.events.add('render', (veh) => {

    mp.vehicles.forEachInStreamRange(
        (veh) => {
            let minDist = 99999;
            var playerPos = mp.players.local.position;



            var vehDist = mp.game.gameplay.getDistanceBetweenCoords(playerPos.x, playerPos.y, playerPos.z, veh.position.x, veh.position.y, veh.position.z, true)
            if (vehDist > 15) return
            for (let i = 0; i < mp.vehicles.length; i++) {
                var minDistCar = mp.game.gameplay.getDistanceBetweenCoords(playerPos.x, playerPos.y, playerPos.z, mp.vehicles[i].position.x, mp.vehicles[i].position.y, mp.vehicles[i].position.z, true)

                if (minDistCar < 2) {
                    mp.gui.chat.push('test ' + minDistCar)

                }

            } 

        }
    )

})

И все, вроде бы, работает, но если машины стоят очень близко друг к другу, то все равно считывает координаты обоих, да и как обращаться тогда к машине ближе - не понятно
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,766
1,574
211
28
Я тебе выше объяснял, что render для этой задачи - плохая мысль, но ты дальше пишешь вот это:

JavaScript:
mp.events.add('render', (veh) => {

    mp.vehicles.forEachInStreamRange(

Нет слов, одни эмоции.
Вот бы у меня на компьютере 100 раз в секунду происходило вычисление по ВСЕМ машинам в зоне стрима, без этого ведь никак, нужно именно каждый кадр и не меньше.

Посмотрел дальше - стало плохо.
 
Последнее редактирование:

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Я тебе выше объяснял, что render для этой задачи - плохая мысль, но ты дальше пишешь вот это:

JavaScript:
mp.events.add('render', (veh) => {

    mp.vehicles.forEachInStreamRange(

Нет слов, одни эмоции. Вот бы у меня на компьютере 100 раз в секунду происходило вычисление по ВСЕМ машинам в зоне стрима, без этого ведь никак, нужно именно каждый кадр и не меньше.
Позже переделаю на таймер, это я понял, в данный момент мне требуется немного другое
 

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Окей, слегка переделал, но все еще криво работает
JavaScript:
mp.vehicles.forEachInStreamRange((veh) => {

        var playerPos = mp.players.local.position; // берем позицию игрока

        for (let i = 0; i < mp.vehicles.length; i++) {
            var vehDist = mp.game.gameplay.getDistanceBetweenCoords(playerPos.x, playerPos.y, playerPos.z, mp.vehicles[i].position.x, mp.vehicles[i].position.y, mp.vehicles[i].position.z, true)
            var AllvehDist = mp.game.gameplay.getDistanceBetweenCoords(playerPos.x, playerPos.y, playerPos.z, veh.position.x, veh.position.y, veh.position.z, true);
            if (AllvehDist > 5) return
            if (vehDist < AllvehDist) {
                mp.game.graphics.drawText(`ID ${veh.id} - MODEL: ${mp.game.vehicle.getDisplayNameFromVehicleModel(veh.getModel())}\nX: ${veh.position.x.toFixed(3)} Y: ${veh.position.y.toFixed(3)} Z: ${veh.position.z.toFixed(3)}`, [veh.position.x, veh.position.y, veh.position.z], {
                    font: 4,
                    color: [255, 255, 255, 185],
                    scale: [0.5, 0.5]
                });
            }
        }

Проблема в том что проверка vehDist < AllvehDist не работает как надо, он спокойно может выбрать рядом стоящие машины.
 
Последнее редактирование:

koltr

Гуру
BackEnd developer
14 Сен 2020
157
108
121
Долго я не отвечал на форуме, но слишком уж замудрили


JavaScript:
const position = mp.players.local.position; // берем позицию игрока
const distanceMax = 10;

let nearVehicle = mp.vehicles[0];
let nearDistance = mp.game.gameplay.getDistanceBetweenCoords(position.x, position.y, position.z, nearVehicle.position.x, nearVehicle.position.y, nearVehicle.position.z, true);

mp.vehicles.forEachInStreamRange((veh) => {

    let vehicleDistance = mp.game.gameplay.getDistanceBetweenCoords(position.x, position.y, position.z, veh.position.x, veh.position.y, veh.position.z, true);

    if (vehicleDistance < nearDistance)
    {
        nearDistance = vehicleDistance;
        nearVehicle = veh;
    }
}

if (nearVehicle != undefined && distanceMax >= nearDistance)
    mp.game.graphics.drawText(`ID ${nearVehicle.remoteId} - MODEL: ${mp.game.vehicle.getDisplayNameFromVehicleModel(nearVehicle.getModel())}\nX: ${nearVehicle.position.x.toFixed(3)} Y: ${nearVehicle.position.y.toFixed(3)} Z: ${nearVehicle.position.z.toFixed(3)}`, [nearVehicle.position.x, nearVehicle.position.y, nearVehicle.position.z], {
        font: 4,
        color: [255, 255, 255, 185],
        scale: [0.5, 0.5]
    });
 
Реакции: kenz и FireFeed

dreamharakiri

Новый участник
25 Дек 2021
75
1
49
Долго я не отвечал на форуме, но слишком уж замудрили


JavaScript:
const position = mp.players.local.position; // берем позицию игрока
const distanceMax = 10;

let nearVehicle = mp.vehicles[0];
let nearDistance = mp.game.gameplay.getDistanceBetweenCoords(position.x, position.y, position.z, nearVehicle.position.x, nearVehicle.position.y, nearVehicle.position.z, true);

mp.vehicles.forEachInStreamRange((veh) => {

    let vehicleDistance = mp.game.gameplay.getDistanceBetweenCoords(position.x, position.y, position.z, veh.position.x, veh.position.y, veh.position.z, true);

    if (vehicleDistance < nearDistance)
    {
        nearDistance = vehicleDistance;
        nearVehicle = veh;
    }
}

if (nearVehicle != undefined && distanceMax >= nearDistance)
    mp.game.graphics.drawText(`ID ${nearVehicle.remoteId} - MODEL: ${mp.game.vehicle.getDisplayNameFromVehicleModel(nearVehicle.getModel())}\nX: ${nearVehicle.position.x.toFixed(3)} Y: ${nearVehicle.position.y.toFixed(3)} Z: ${nearVehicle.position.z.toFixed(3)}`, [nearVehicle.position.x, nearVehicle.position.y, nearVehicle.position.z], {
        font: 4,
        color: [255, 255, 255, 185],
        scale: [0.5, 0.5]
    });
В целом тоже самое что и у меня, к сожалению, не работает как надо, рисует на всех машинах в радиусе 10 :(
 

koltr

Гуру
BackEnd developer
14 Сен 2020
157
108
121