• Из-за обновления 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) последний раз были обновлены:

Вопрос Как создать NPC охраняющего территорию

Статус
В этой теме нельзя размещать новые ответы.

Irvin

Начинающий специалист
11 Июл 2021
97
10
65
Всем привет. Может кто знает как правильно написать логику для NPC? Чтобы с оружием в руках охранял территорию. Я попробовал написать сам но по итогу NPC появляется но без оружия и не на кого не нападает.
JavaScript:
// На стороне сервера

const guardPosition = new mp.Vector3(0, 0, 0); 
const guardHeading = 0; 
const guardRange = 20; 
const weaponHash = 0x83BF0278; // WEAPON_CARBINERIFLE
const respawnTime = 20000; // Время респавна в миллисекундах (20 секунд)

let guard = null;
let respawnTimeout = null;

mp.events.add('playerJoin', (player) => {
    if (guard === null && respawnTimeout === null) {
        createGuard();
    }
});

function createGuard() {
    guard = mp.peds.new(0x8D8F1B10, guardPosition, guardHeading, 0); // s_m_y_swat_01
   
    // Устанавливаем здоровье и броню для NPC
    guard.health = 100;
    guard.armour = 100;
   
    // Отправляем событие клиентам для установки оружия NPC
    mp.players.call('setGuardWeapon', [guard.id, weaponHash]);
   
    // Добавляем обработчик смерти NPC
    guard.setVariable('isGuard', true);
    mp.events.add('pedDeath', (ped) => {
        if (ped.getVariable('isGuard')) {
            console.log('NPC охранник умер. Респавн через 20 секунд.');
            guard = null;
            clearTimeout(respawnTimeout);
            respawnTimeout = setTimeout(() => {
                createGuard();
                console.log('NPC охранник респавнен.');
                respawnTimeout = null;
            }, respawnTime);
        }
    });
}

setInterval(() => {
    if (guard === null) return;

    mp.players.forEachInRange(guardPosition, guardRange, (player) => {
        if (player.type === 'player') {
            // Используем taskShootAt для стрельбы по игрокам
            guard.taskShootAt(player, -1, 0);
        }
    });
}, 1000); // Проверка каждую секунду

mp.events.addCommand('respawnguard', (player) => {
    if (player.adminLevel < 1) return; // Проверка на права администратора
    if (guard !== null) {
        guard.destroy();
    }
    clearTimeout(respawnTimeout);
    createGuard();
    player.outputChatBox('NPC охранник респавнен.');
});

JavaScript:
//На клиентской

mp.events.add('setGuardWeapon', (guardId, weaponHash) => {
    const guard = mp.peds.atRemoteId(guardId);
    if (guard) {
        guard.giveWeapon(weaponHash, 1000); // Даем 1000 патронов
        guard.setCurrentWeapon(weaponHash);
    }
});
 
Последнее редактирование:

kiraz

Специалист
17 Апр 2023
407
135
83
а зачем делать при входе? переделай ивент со входа игрока на вход в зону стрима. + делай это не на сервере, а локально на клиенте
 

Irvin

Начинающий специалист
11 Июл 2021
97
10
65
а зачем делать при входе? переделай ивент со входа игрока на вход в зону стрима. + делай это не на сервере, а локально на клиенте
Так будет правильно если локально?

JavaScript:
const WEAPON_HASH = mp.game.joaat("WEAPON_CARBINERIFLE");
const GUARD_POSITION = new mp.Vector3(100, 100, 50);
const GUARD_HEADING = 180.0; // Направление, в котором смотрит NPC
const PROTECTION_RANGE = 20.0; // Радиус защищаемой зоны

let guardNPC;

// Создание NPC-охранника
mp.events.add('playerReady', () => {
    guardNPC = mp.peds.new(mp.game.joaat("s_m_y_swat_01"), GUARD_POSITION, GUARD_HEADING, 0);
    guardNPC.setArmour(100);
    guardNPC.setHealth(100);
    guardNPC.giveWeapon(WEAPON_HASH, 1000, true);
});

// Функция для проверки, находится ли игрок в зоне защиты
function isPlayerInProtectionZone(player) {
    const distance = GUARD_POSITION.distance(player.position);
    return distance <= PROTECTION_RANGE;
}

// Функция для стрельбы в игрока
function shootAtPlayer(player) {
    guardNPC.taskShootAt(player.handle, 2000, mp.game.joaat("FIRING_PATTERN_FULL_AUTO"));
}

// Основной цикл проверки игроков
setInterval(() => {
    mp.players.forEachInStreamRange(player => {
        if (player !== mp.players.local && isPlayerInProtectionZone(player)) {
            shootAtPlayer(player);
        }
    });
}, 1000); // Проверка каждую секунду

// Отладочная информация (опционально)
mp.events.add('render', () => {
    mp.game.graphics.drawText(`NPC Guard Active: ${guardNPC !== undefined}`, [0.5, 0.05], {
        font: 4,
        color: [255, 255, 255, 255],
        scale: [0.5, 0.5],
        outline: true
    });
});
 

kiraz

Специалист
17 Апр 2023
407
135
83
Так будет правильно если локально?

JavaScript:
const WEAPON_HASH = mp.game.joaat("WEAPON_CARBINERIFLE");
const GUARD_POSITION = new mp.Vector3(100, 100, 50);
const GUARD_HEADING = 180.0; // Направление, в котором смотрит NPC
const PROTECTION_RANGE = 20.0; // Радиус защищаемой зоны

let guardNPC;

// Создание NPC-охранника
mp.events.add('playerReady', () => {
    guardNPC = mp.peds.new(mp.game.joaat("s_m_y_swat_01"), GUARD_POSITION, GUARD_HEADING, 0);
    guardNPC.setArmour(100);
    guardNPC.setHealth(100);
    guardNPC.giveWeapon(WEAPON_HASH, 1000, true);
});

// Функция для проверки, находится ли игрок в зоне защиты
function isPlayerInProtectionZone(player) {
    const distance = GUARD_POSITION.distance(player.position);
    return distance <= PROTECTION_RANGE;
}

// Функция для стрельбы в игрока
function shootAtPlayer(player) {
    guardNPC.taskShootAt(player.handle, 2000, mp.game.joaat("FIRING_PATTERN_FULL_AUTO"));
}

// Основной цикл проверки игроков
setInterval(() => {
    mp.players.forEachInStreamRange(player => {
        if (player !== mp.players.local && isPlayerInProtectionZone(player)) {
            shootAtPlayer(player);
        }
    });
}, 1000); // Проверка каждую секунду

// Отладочная информация (опционально)
mp.events.add('render', () => {
    mp.game.graphics.drawText(`NPC Guard Active: ${guardNPC !== undefined}`, [0.5, 0.05], {
        font: 4,
        color: [255, 255, 255, 255],
        scale: [0.5, 0.5],
        outline: true
    });
});
прекрати использовать чат гпт. используй для каких то рутинных задач. переделай с playerReady на
 
  • Like
Реакции: Inoi и XDeveluxe

Irvin

Начинающий специалист
11 Июл 2021
97
10
65

Irvin

Начинающий специалист
11 Июл 2021
97
10
65
Вот что может быть не правильно? всё же вроде нормально написал а он теперь вообще перестал спавнить NPC

JavaScript:
// Функция для создания NPC-охранника
function createGuardNPC() {
    if (!guardNPC) {
        guardNPC = mp.peds.new(mp.game.joaat("s_m_y_swat_01"), GUARD_POSITION, GUARD_HEADING, 0);
        guardNPC.setArmour(100);
        guardNPC.setHealth(100);
        guardNPC.giveWeapon(WEAPON_HASH, 1000, true);
        console.log("NPC Guard created");
    }
}

// Функция для удаления NPC-охранника
function removeGuardNPC() {
    if (guardNPC) {
        guardNPC.destroy();
        guardNPC = null;
        console.log("NPC Guard removed");
    }
}

// Создание NPC-охранника при входе в зону стрима
mp.events.add('entityStreamIn', (entity) => {
    if (entity.type === 'player' && entity !== mp.players.local) {
        const distance = GUARD_POSITION.distance(entity.position);
        if (distance <= STREAM_DISTANCE) {
            createGuardNPC();
        }
    }
});

// Удаление NPC-охранника при выходе из зоны стрима
mp.events.add('entityStreamOut', (entity) => {
    if (entity.type === 'player' && entity !== mp.players.local) {
        const distance = GUARD_POSITION.distance(mp.players.local.position);
        if (distance > STREAM_DISTANCE) {
            removeGuardNPC();
        }
    }
});
 

Reys

Специалист
25 Май 2023
368
194
87
Сложилось ощущение что ты дрочишь ЖПТ чат, а у нас спрашиваешь что ему еще написать чтобы получилось
 

XDeveluxe

Модератор
Команда форума
high coder
30 Авг 2021
2,396
1,612
211
27
жпт не трогаю, он херню вечно выдаёт.
Свечку не держал, но комментарии в коде как у тебя - чисто ЖПТвщина, который комментирует каждую строку абсолютно, даже там, где это не надо.
 

Irvin

Начинающий специалист
11 Июл 2021
97
10
65
Свечку не держал, но комментарии в коде как у тебя - чисто ЖПТвщина, который комментирует каждую строку абсолютно, даже там, где это не надо.
это я для себя комментирую так как я новичок и могу запутаться в коде. В ютюбе так учителя рекомендуют делать в первое время.
 

XDeveluxe

Модератор
Команда форума
high coder
30 Авг 2021
2,396
1,612
211
27
Дело в том, что полностью синхронизированных NPC на RAGEMP до сих пор нет. Они пытаются, но всё ещё пока что нет.
В данный момент NPC способны получать какие-либо указания только в момент, когда они находятся в радиусе прорисовки (то есть триггернулись в ивенте entityStreamIn, как указали выше) кого-то (то есть игрока) и этот кто-то (то есть игрок) является их контроллером, и отдаёт им задачи со своего клиента (то есть компьютера). То, что ты хочешь сделать - можно сделать, но это будет работать через 5 костылей и по итогу окажется совсем не так красиво, как ты себе представляешь. Поэтому до полной поддержки рейджом синхронизации NPC - я бы не рекомендовал туда лезть вообще.
 

Irvin

Начинающий специалист
11 Июл 2021
97
10
65
Дело в том, что полностью синхронизированных NPC на RAGEMP до сих пор нет. Они пытаются, но всё ещё пока что нет.
В данный момент NPC способны получать какие-либо указания только в момент, когда они находятся в радиусе прорисовки (то есть триггернулись в ивенте entityStreamIn, как указали выше) кого-то (то есть игрока) и этот кто-то (то есть игрок) является их контроллером, и отдаёт им задачи со своего клиента (то есть компьютера). То, что ты хочешь сделать - можно сделать, но это будет работать через 5 костылей и по итогу окажется совсем не так красиво, как ты себе представляешь. Поэтому до полной поддержки рейджом синхронизации NPC - я бы не рекомендовал туда лезть вообще.
мне синхра не обязательна, просто хочу понять как правильно написать код чтобы это работало. Говоришь контролёр нужен обязательно, я просто без него делаю, попробую с контролёром значит. С стрим зоной разобрался и работает нормально. Вот только почему то не агриться на игроков
 

XDeveluxe

Модератор
Команда форума
high coder
30 Авг 2021
2,396
1,612
211
27
мне синхра не обязательна, просто хочу понять как правильно написать код чтобы это работало. Говоришь контролёр нужен обязательно, я просто без него делаю, попробую с контролёром значит. С стрим зоной разобрался и работает нормально. Вот только почему то не агриться на игроков
Если синхронизация не обязательна, то серверный код тебе вообще не нужен - всё делаешь на клиенте.
Чтобы он агрился - нужно дать такую задачу в момент, когда NPC прорисован у игрока.
Ну и убедиться, что команда дана верная.
 

Vermilion

Мастер
29 Сен 2021
970
741
151
34
У тебя не срабатывает entityStreamIn потому что у тебя нет сущности которая должна появиться в стриме, что бы тригернуть создание педа. (Так как он еще не создан)
Создай колшейп и добавь обработчики событий которые будут создавать педа, когда игрок заходит в зону и соответственно удалять когда игрок выходит из зоны.
 

XDeveluxe

Модератор
Команда форума
high coder
30 Авг 2021
2,396
1,612
211
27
Код:
// Функция для стрельбы в игрока
function shootAtPlayer(player) {
    guardNPC.taskShootAt(player.handle, 2000, mp.game.joaat("FIRING_PATTERN_FULL_AUTO"));
}
Например тут - вообще не знаю откуда взялся taskShootAt, если на ragemp wiki функция записана как taskCombat
На C# клиентке он действительно TaskShootAt, а на JS называется taskCombat.

Код:
// Основной цикл проверки игроков
setInterval(() => {
    mp.players.forEachInStreamRange(player => {
        if (player !== mp.players.local && isPlayerInProtectionZone(player)) {
            shootAtPlayer(player);
        }
    });
}, 1000); // Проверка каждую секунду
А вот здесь ты вообще проверяешь на всех игроков, кроме локального. То есть в ТЕБЯ NPC никогда стрелять не будет.
А если NPC клиентский, то у другого игрока он отрисован так, как у тебя - не будет, а значит даже если он будет стрелять в него на твоём экране - на его экране этого не будет.
 

kiraz

Специалист
17 Апр 2023
407
135
83
Сложилось ощущение что ты дрочишь ЖПТ чат, а у нас спрашиваешь что ему еще написать чтобы получилось
я с момента прочтения первого сообщения в треде сразу заподозрил неладное..
 
  • Like
Реакции: Inoi

Vermilion

Мастер
29 Сен 2021
970
741
151
34
А чего вы так хуесосите жпт? Нормальная тема :)
 

delakses

Участник портала
19 Ноя 2024
63
4
8
Ребятки специалисты и профессионалы-подскажите где и по какому пути поставить при регистрации персонажу сразу 1 уровень
 

DonLeo

Начинающий специалист
22 Ноя 2020
19
8
65
34
Ребятки специалисты и профессионалы-подскажите где и по какому пути поставить при регистрации персонажу сразу 1 уровень
Так ували в запись в бд запрос при регистрации не «0» а «1» ну самое просто что можно сделать
 
  • Like
Реакции: delakses
Статус
В этой теме нельзя размещать новые ответы.