• Из-за обновления 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
98
7
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
426
89
83
а зачем делать при входе? переделай ивент со входа игрока на вход в зону стрима. + делай это не на сервере, а локально на клиенте
 

Irvin

Участник портала
11 Июл 2021
98
7
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
426
89
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 на
 
Реакции: Inoi и XDeveluxe

Irvin

Участник портала
11 Июл 2021
98
7
65

Irvin

Участник портала
11 Июл 2021
98
7
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
440
200
87
Сложилось ощущение что ты дрочишь ЖПТ чат, а у нас спрашиваешь что ему еще написать чтобы получилось
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,919
1,671
211
28
жпт не трогаю, он херню вечно выдаёт.
Свечку не держал, но комментарии в коде как у тебя - чисто ЖПТвщина, который комментирует каждую строку абсолютно, даже там, где это не надо.
 

Irvin

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

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,919
1,671
211
28
Дело в том, что полностью синхронизированных NPC на RAGEMP до сих пор нет. Они пытаются, но всё ещё пока что нет.
В данный момент NPC способны получать какие-либо указания только в момент, когда они находятся в радиусе прорисовки (то есть триггернулись в ивенте entityStreamIn, как указали выше) кого-то (то есть игрока) и этот кто-то (то есть игрок) является их контроллером, и отдаёт им задачи со своего клиента (то есть компьютера). То, что ты хочешь сделать - можно сделать, но это будет работать через 5 костылей и по итогу окажется совсем не так красиво, как ты себе представляешь. Поэтому до полной поддержки рейджом синхронизации NPC - я бы не рекомендовал туда лезть вообще.
 

Irvin

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

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,919
1,671
211
28
мне синхра не обязательна, просто хочу понять как правильно написать код чтобы это работало. Говоришь контролёр нужен обязательно, я просто без него делаю, попробую с контролёром значит. С стрим зоной разобрался и работает нормально. Вот только почему то не агриться на игроков
Если синхронизация не обязательна, то серверный код тебе вообще не нужен - всё делаешь на клиенте.
Чтобы он агрился - нужно дать такую задачу в момент, когда NPC прорисован у игрока.
Ну и убедиться, что команда дана верная.
 

Vermilion

Высший разум
High developer
BackEnd developer
FrontEnd developer
29 Сен 2021
1,355
806
181
34
У тебя не срабатывает entityStreamIn потому что у тебя нет сущности которая должна появиться в стриме, что бы тригернуть создание педа. (Так как он еще не создан)
Создай колшейп и добавь обработчики событий которые будут создавать педа, когда игрок заходит в зону и соответственно удалять когда игрок выходит из зоны.
 

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,919
1,671
211
28
Код:
// Функция для стрельбы в игрока
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 клиентский, то у другого игрока он отрисован так, как у тебя - не будет, а значит даже если он будет стрелять в него на твоём экране - на его экране этого не будет.
 

Vermilion

Высший разум
High developer
BackEnd developer
FrontEnd developer
29 Сен 2021
1,355
806
181
34
А чего вы так хуесосите жпт? Нормальная тема :)
 

delakses

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

DonLeo

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