This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

Вопрос Как создать 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
прекрати использовать чат гпт. используй для каких то рутинных задач. переделай с 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,934
1,676
211
28
жпт не трогаю, он херню вечно выдаёт.
Свечку не держал, но комментарии в коде как у тебя - чисто ЖПТвщина, который комментирует каждую строку абсолютно, даже там, где это не надо.
 

Irvin

Участник портала
11 Июл 2021
98
7
65
это я для себя комментирую так как я новичок и могу запутаться в коде. В ютюбе так учителя рекомендуют делать в первое время.
 

XDeveluxe

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

Irvin

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

XDeveluxe

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

Vermilion

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

XDeveluxe

⚡️BackEnd Developer
Команда форума
Moderator
High developer
BackEnd developer
30 Авг 2021
2,934
1,676
211
28
Например тут - вообще не знаю откуда взялся taskShootAt, если на ragemp wiki функция записана как taskCombat
На C# клиентке он действительно TaskShootAt, а на JS называется taskCombat.

А вот здесь ты вообще проверяешь на всех игроков, кроме локального. То есть в ТЕБЯ NPC никогда стрелять не будет.
А если NPC клиентский, то у другого игрока он отрисован так, как у тебя - не будет, а значит даже если он будет стрелять в него на твоём экране - на его экране этого не будет.
 

Vermilion

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

delakses

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

DonLeo

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

Similar threads