FiveM Pet and Companion System: Скрипт верных напарников
Добавьте питомцев и компаньонов на ваш сервер FiveM. Следование за игроком, кормление, магазины, кастомные модели и лучшие скрипты питомцев для QBCore и ESX.
Agency Scripts
Основатель и ведущий разработчик Agency Scripts
Питомцы как живые компаньоны для ролевой игры
Питомцы приносят уникальное эмоциональное измерение на ролевые серверы, которое не может воспроизвести ни одна другая система. Игрок, идущий по городу с собакой рядом, создаёт визуальную индивидуальность, которая обогащает каждое взаимодействие. Питомцы превращают обыденные действия, такие как поход в магазин, в захватывающие моменты. Они создают органичные темы для разговоров, когда другие игроки замечают вашего немецкого овчара или спрашивают о вашей кошке. Помимо социальной составляющей, питомцы могут выполнять функциональные роли: сторожевые собаки, предупреждающие владельцев о незваных гостях, полицейские собаки, помогающие в поисках, животные эмоциональной поддержки в больничных ролевых играх или охотничьи компаньоны, помогающие отслеживать добычу. Создание системы питомцев требует обработки спавна и деспавна педи, поведения ИИ при следовании, интеграции анимаций, симуляции потребностей, таких как голод и счастье, сохранения между сессиями и команд взаимодействия, позволяющих владельцу управлять питомцем через естественные жесты и голосовые команды.
Доступные модели животных и конфигурация
В GTA V есть несколько моделей животных пешеходов, которые хорошо подходят в качестве компаньонов. Собаки самые универсальные с моделями, такими как a_c_shepherd для немецких овчарок, a_c_husky для хаски, a_c_poodle для пуделей, a_c_rottweiler для ротвейлеров, a_c_retriever для ретриверов, и a_c_chop для культовой модели Chop. Кошки используют a_c_cat_01. Для экзотических вариантов есть кролики с a_c_rabbit_01 и даже птиц с a_c_crow. Для каждого типа питомца должны быть настроены разные параметры поведения в общем файле. Собаки следуют близко и могут бегать рядом с транспортом на умеренной скорости. Кошки более независимы, иногда уходят на короткие расстояния, а затем возвращаются. Птицы могут садиться на плечо игрока с помощью прикрепления сущности. Определите дистанцию следования, множитель скорости движения, анимации бездействия, анимации взаимодействия и специальные способности для каждого типа питомца, чтобы создать уникальные личности для каждого вида.
-- shared/config.lua
Config = {}
Config.PetTypes = {
shepherd = {
model = 'a_c_shepherd',
label = 'German Shepherd',
price = 5000,
followDist = 2.5,
runDist = 8.0,
maxSpeed = 7.0,
category = 'dog',
abilities = {'guard', 'fetch', 'search'},
idleAnims = {'sit', 'lie_down', 'sniff'},
},
husky = {
model = 'a_c_husky',
label = 'Husky',
price = 6000,
followDist = 3.0,
runDist = 10.0,
maxSpeed = 8.0,
category = 'dog',
abilities = {'fetch', 'howl'},
idleAnims = {'sit', 'lie_down', 'play'},
},
cat = {
model = 'a_c_cat_01',
label = 'Cat',
price = 2000,
followDist = 4.0,
runDist = 6.0,
maxSpeed = 5.0,
category = 'cat',
abilities = {'purr', 'hunt_rodent'},
idleAnims = {'sit', 'groom', 'sleep'},
},
poodle = {
model = 'a_c_poodle',
label = 'Poodle',
price = 4000,
followDist = 2.0,
runDist = 6.0,
maxSpeed = 5.5,
category = 'dog',
abilities = {'fetch', 'trick'},
idleAnims = {'sit', 'beg', 'spin'},
},
rottweiler = {
model = 'a_c_rottweiler',
label = 'Rottweiler',
price = 7000,
followDist = 2.0,
runDist = 8.0,
maxSpeed = 7.5,
category = 'dog',
abilities = {'guard', 'attack', 'intimidate'},
idleAnims = {'sit', 'lie_down', 'bark'},
},
}
Поведение при спавне и следовании
Ядро любой системы питомцев , это AI следования, который заставляет животное естественно идти за своим владельцем. Когда игрок вызывает питомца, создайте педа в его позиции с помощью CreatePed с подходящей моделью. Установите педа как непостоянного с помощью SetEntityAsMissionEntity и настройте его так, чтобы он был дружелюбен к владельцу, используя группы отношений. Поведение следования использует клиентский цикл, который постоянно вычисляет расстояние между питомцем и владельцем. Когда расстояние превышает порог следования, задайте питомцу задачу бежать к позиции немного позади и сбоку от владельца с помощью TaskFollowToOffsetOfEntity. Этот native автоматически обрабатывает поиск пути, позволяя питомцу обходить препятствия, ходить по тротуарам и избегать движения транспорта. Когда владелец перестает двигаться и питомец достигает дистанции следования, воспроизводится анимация бездействия, например сидение или лежание. Если владелец садится в транспорт и уезжает, питомец телепортируется в транспорт, если он подходящего типа, или питомец исчезает и появляется снова, когда владелец выходит из транспорта, чтобы предотвратить потерю питомца по карте.
-- client/pet_behavior.lua
local activePet = nil
local petData = nil
function SpawnPet(petType, name)
if activePet then DespawnPet() end
local config = Config.PetTypes[petType]
if not config then return end
local ped = PlayerPedId()
local coords = GetOffsetFromEntityInWorldCoords(ped, 1.5, 1.5, 0.0)
RequestModel(config.model)
while not HasModelLoaded(config.model) do Wait(10) end
activePet = CreatePed(28, config.model,
coords.x, coords.y, coords.z, 0.0, true, false)
SetEntityAsMissionEntity(activePet, true, true)
SetBlockingOfNonTemporaryEvents(activePet, true)
SetPedCanBeTargetted(activePet, false)
SetPedCanRagdoll(activePet, false)
-- Set relationship so pet doesn't attack owner
local playerGroup = GetHashKey('PLAYER')
local petGroup = GetHashKey('PET_COMPANION')
AddRelationshipGroup('PET_COMPANION')
SetPedRelationshipGroupHash(activePet, petGroup)
SetRelationshipBetweenGroups(0, petGroup, playerGroup)
SetRelationshipBetweenGroups(0, playerGroup, petGroup)
petData = {type = petType, name = name, config = config}
-- Start follow loop
CreateThread(PetFollowLoop)
end
function PetFollowLoop()
while activePet and DoesEntityExist(activePet) do
local ped = PlayerPedId()
local petCoords = GetEntityCoords(activePet)
local ownerCoords = GetEntityCoords(ped)
local dist = #(petCoords - ownerCoords)
if dist > 50.0 then
-- Teleport if too far
SetEntityCoords(activePet,
ownerCoords.x, ownerCoords.y, ownerCoords.z)
elseif dist > petData.config.runDist then
-- Run to owner
TaskFollowToOffsetOfEntity(activePet, ped,
0.0, -1.5, 0.0, petData.config.maxSpeed,
-1, 1.0, true)
elseif dist > petData.config.followDist then
-- Walk to owner
TaskFollowToOffsetOfEntity(activePet, ped,
0.0, -1.5, 0.0, 2.0, -1, 1.0, true)
else
-- Idle nearby
if not IsEntityPlayingAnim(activePet, 'creatures@dog@amb@', 'sit_enter', 3) then
if math.random() > 0.95 then
PlayIdleAnimation()
end
end
end
Wait(500)
end
end
Потребности питомцев и система привязанности
Система потребностей придаёт владению питомцем постоянную ответственность и глубину. Отслеживайте голод, счастье и здоровье как значения от 0 до 100, которые уменьшаются в реальном времени. Голод уменьшается на 1 пункт каждые 5 минут реального времени, пока питомец активен. Счастье уменьшается медленнее , на 1 пункт каждые 10 минут, но значительно увеличивается при взаимодействии владельца с питомцем: поглаживании, игре с мячом или угощениях. Здоровье остаётся на 100, если голод не опускается ниже 20, после чего начинает снижаться. При голоде 0 питомец становится вялым с замедленными движениями и грустными анимациями. При слишком низком здоровье питомцу нужна ветеринарная помощь для восстановления. Игроки кормят питомцев, используя пищевые предметы из инвентаря на сущности питомца. Разные типы еды восстанавливают разное количество голода: базовый корм восстанавливает 30 пунктов, премиум , 60, угощения , 10, но повышают счастье на 15. Уровень привязанности отслеживает накопленные отношения между владельцем и питомцем, увеличиваясь при положительных взаимодействиях и уменьшаясь при пренебрежении. Более высокий уровень привязанности открывает специальные взаимодействия и улучшает отзывчивость питомца на команды.
-- server/pet_needs.lua
local petStates = {}
function InitPetState(ownerId, petId)
petStates[ownerId] = {
petId = petId,
hunger = 100,
happiness = 80,
health = 100,
bond = 0,
lastFed = os.time(),
lastPet = os.time(),
}
end
-- Decay loop runs every 60 seconds
CreateThread(function()
while true do
Wait(60000)
local now = os.time()
for ownerId, state in pairs(petStates) do
-- Hunger decay: 1 point per 5 minutes
local minutesSinceFed = (now - state.lastFed) / 60
state.hunger = math.max(0,
100 - math.floor(minutesSinceFed / 5))
-- Happiness decay
local minutesSincePet = (now - state.lastPet) / 60
state.happiness = math.max(0,
math.min(100, state.happiness -
math.floor(minutesSincePet / 10)))
-- Health decays when starving
if state.hunger < 20 then
state.health = math.max(0,
state.health - 1)
end
-- Sync to client
local player = GetPlayerFromIdentifier(ownerId)
if player then
TriggerClientEvent('pet:syncState', player, state)
end
end
end
end)
RegisterNetEvent('pet:feed', function(foodItem)
local src = source
local id = GetPlayerIdentifier(src, 0)
local state = petStates[id]
if not state then return end
local foodValues = {
petfood = {hunger = 30, happiness = 5},
premium_food = {hunger = 60, happiness = 10},
pet_treat = {hunger = 10, happiness = 15},
}
local food = foodValues[foodItem]
if not food then return end
-- Remove item from inventory
local removed = exports['ox_inventory']:RemoveItem(src, foodItem, 1)
if not removed then return end
state.hunger = math.min(100, state.hunger + food.hunger)
state.happiness = math.min(100, state.happiness + food.happiness)
state.lastFed = os.time()
state.bond = state.bond + 1
TriggerClientEvent('pet:syncState', src, state)
TriggerClientEvent('pet:feedAnimation', src)
end)
Команды взаимодействия и анимации
Дайте игрокам широкий набор команд для взаимодействия с их питомцем. Радиальное меню или система команд должны предлагать опции, такие как сидеть, оставаться, следовать, идти сюда, лечь, пожать лапу, приносить и говорить. Каждая команда запускает соответствующую анимацию на питомце-педе с использованием словарей анимаций существ, встроенных в GTA V. Команда сидеть использует анимации из creatures@dog@amb@ с клипами sit_enter и sit_loop. Лежать использует похожие амбиентные анимации. Для fetch создайте небольшой проп-шар, бросьте его по параболической траектории и поручите питомцу бежать к месту приземления шара, подобрать его с помощью прикрепления и вернуть владельцу. Команда speak запускает звук лая с помощью PlayPedAmbientSpeechNative. Для поглаживания воспроизводите анимацию на коленях у игрока одновременно с анимацией радостного виляния хвостом у питомца. Эти взаимодействия не просто косметические; каждое из них увеличивает показатели счастья и связи, вознаграждая игроков, которые активно взаимодействуют со своим компаньоном, а не рассматривают его как пассивного спутника.
Сохранение данных и интеграция с питомниками
Домашние животные должны сохраняться между сессиями сервера, чтобы игроки не теряли своих питомцев при каждом рестарте. Храните данные питомцев в базе данных, включая идентификатор владельца, тип питомца, кастомное имя, текущие показатели потребностей, уровень привязанности и любые разблокированные трюки или способности. При входе владельца в игру запрашивайте данные о его питомце и предлагайте вызвать его через команду или автоматически, если питомец был активен при последнем отключении. Интегрируйте приобретение питомцев через внутриигровой зоомагазин, расположенный в логичном месте на карте. NUI зоомагазина отображает доступные типы питомцев с их моделями в превью, цены и описания. После покупки игрок называет нового питомца, и он появляется рядом с ним. Рассмотрите возможность добавления центра по усыновлению питомцев как альтернативы с более низкими ценами, но случайным выбором типов питомцев, что добавит благотворительный ролевой аспект. Для экономики сервера питомцы могут требовать периодических расходов, таких как визиты к ветеринару для восстановления здоровья, уход за внешним видом для бонусов и тренировки, открывающие новые анимации команд, создавая реалистичные затраты на содержание питомца, интегрированные с вашей общей экономической системой.
-- SQL schema
CREATE TABLE IF NOT EXISTS pets (
id INT AUTO_INCREMENT PRIMARY KEY,
owner_id VARCHAR(64) NOT NULL,
char_slot INT DEFAULT 1,
pet_type VARCHAR(32) NOT NULL,
pet_name VARCHAR(64) NOT NULL,
hunger INT DEFAULT 100,
happiness INT DEFAULT 80,
health INT DEFAULT 100,
bond INT DEFAULT 0,
tricks JSON DEFAULT '[]',
is_active TINYINT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
INDEX idx_owner (owner_id, char_slot)
);
-- server/persistence.lua
function SavePet(ownerId, charSlot, state)
MySQL.update([[
UPDATE pets SET
hunger = ?, happiness = ?, health = ?,
bond = ?, is_active = 1, updated_at = NOW()
WHERE owner_id = ? AND char_slot = ?
]], {
state.hunger, state.happiness, state.health,
state.bond, ownerId, charSlot
})
end
function LoadPet(ownerId, charSlot)
return MySQL.single.await([[
SELECT * FROM pets
WHERE owner_id = ? AND char_slot = ?
AND is_active = 1
]], {ownerId, charSlot})
end
Интеграция полиции с кинологической службой и специальными ролями
Для ролевой игры правоохранительных органов расширьте систему питомцев до полноценной интеграции K-9 подразделения. Полицейские собаки получают особые способности, недоступные гражданским питомцам. Команда поиска заставляет K-9 обнюхивать ближайшие транспортные средства или здания и сигнализировать о настраиваемых запрещённых предметах, лаем и садясь рядом с источником. Реализуйте это, проверяя инвентари ближайших игроков или багажники машин на наличие отмеченных предметов при выполнении команды поиска. Команда отслеживания заставляет K-9 следовать по следу запаха, который можно реализовать, создавая цепочку позиций от убегающего подозреваемого и поручая собаке идти по ним. Команда задержания заставляет K-9 бросаться к цели и воспроизводить анимацию атаки, предоставляя офицерам нелетальный способ задержания подозреваемых. Ограничьте эти способности игрокам с должностью полиции и сертификатом кинолога. K-9 должен носить полицейский жилет с помощью вариаций компонентов педа или прикреплённых аксессуаров, чтобы визуально отличаться от гражданских питомцев. Эта специализация создаёт уникальную и востребованную позицию в иерархии полиции.