ESX предметы: таблица items, RegisterUsableItem и addInventoryItem
Добавьте предмет в ESX: таблица SQL items, ESX.RegisterUsableItem, чтобы сделать его пригодным для использования, addInventoryItem, removeInventoryItem, getInventoryItem и canCarryItem, плюс заметка ox_inventory.
Вы хотите новый предмет на вашем сервере ESX: бургер, телефон, отмычку. В ESX предмет — это строка в базе данных, и скрипт дает, удаляет и использует его через объект игрока. Эта статья охватывает таблицу items, делание предмета пригодным для использования, функции xPlayer, которые вы используете каждый день, и что меняется, когда сервер работает с ox_inventory.
Таблица items
ESX читает свои предметы из таблицы items. Ее столбцы:
| Столбец | Значение |
|---|---|
name |
Имя предмета, используемое в коде. Нижний регистр, без пробелов |
label |
Имя, которое видят игроки |
weight |
Вес одного предмета |
rare |
Сохранено для старого использования, обычно 0 |
can_remove |
1, если игроки могут отбросить или удалить предмет |
Добавьте предмет с помощью SQL:
INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`)
VALUES ('burger', 'Burger', 1, 0, 1);Перезагрузите ESX или весь сервер, чтобы он перезагрузил таблицу. Если ваша база данных показывает другой набор столбцов, следите за столбцами, которые она имеет, поскольку версии немного отличаются. Если вы не уверены, как запустить запрос, смотрите oxmysql queries.
Внимание: имя предмета — это ключ.
burgerиBurgerразные, и предмет, добавленный с неправильным написанием, молча не работает в большинстве скриптов.
Сделайте предмет пригодным для использования
Зарегистрируйте предмет на сервере в скрипте:
ESX = exports['es_extended']:getSharedObject()
ESX.RegisterUsableItem('burger', function(source)
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return end
xPlayer.removeInventoryItem('burger', 1)
TriggerClientEvent('my_script:eatBurger', source)
end)Обратный вызов запускается на сервере, когда игрок использует предмет. Он не удаляет предмет сам по себе, поэтому вы удаляете его сами. Сделайте удаление на сервере, затем скажите клиенту воспроизвести анимацию. Если объект равен nil, смотрите ESX is nil: fixing getSharedObject.
На клиенте событие только должно воспроизвести эффект:
RegisterNetEvent('my_script:eatBurger', function()
-- animation, progress bar, hunger update
end)Дайте, удалите и проверьте предметы
Это функции xPlayer, которые вам нужны:
local xPlayer = ESX.GetPlayerFromId(source)
-- give
xPlayer.addInventoryItem('burger', 2)
-- remove
xPlayer.removeInventoryItem('burger', 1)
-- read one item
local item = xPlayer.getInventoryItem('burger')
print(item.count)getInventoryItem возвращает таблицу с по крайней мере count, label и name. Если предмет не существует в таблице, результат может быть nil в некоторых версиях, поэтому проверьте перед чтением count.
Надежный паттерн — проверить перед удалением:
local item = xPlayer.getInventoryItem('lockpick')
if item and item.count >= 1 then
xPlayer.removeInventoryItem('lockpick', 1)
-- do the action
else
xPlayer.showNotification('You need a lockpick')
endСначала проверьте вес: canCarryItem
Перед тем, как дать предмет, спросите, может ли игрок его нести. Если вы этого не сделаете, addInventoryItem может не сработать на полном инвентаре и игрок потеряет награду:
if xPlayer.canCarryItem('burger', 2) then
xPlayer.addInventoryItem('burger', 2)
else
xPlayer.showNotification('You cannot carry that much')
endcanCarryItem(name, count) сравнивает вес предмета со свободным весом игрока. Используйте его везде, где скрипт награждает предметом: работы, крафтинг, добычу. Для других помощников смотрите ESX job setup.
Пример: магазин, продающий предмет
Соберите части на сервере с проверкой денег и веса:
RegisterNetEvent('my_script:buyBurger', function()
local src = source
local xPlayer = ESX.GetPlayerFromId(src)
if not xPlayer then return end
local price = 10
if xPlayer.getAccount('money').money < price then
return xPlayer.showNotification('Not enough money')
end
if not xPlayer.canCarryItem('burger', 1) then
return xPlayer.showNotification('Your inventory is full')
end
xPlayer.removeAccountMoney('money', price)
xPlayer.addInventoryItem('burger', 1)
end)Цена и предмет зафиксированы на сервере. Клиент только говорит "Я хочу бургер", он никогда не отправляет цену. Смотрите securing server events для чего.
ESX с ox_inventory
Многие серверы ESX работают с ox_inventory вместо инвентаря по умолчанию. Затем:
- предметы определяются в
ox_inventory/data/items.lua, а не в таблице SQL - семейство
xPlayer.addInventoryItemвсе еще работает, поскольку ESX передает его ox_inventory ESX.RegisterUsableItemвсе еще работает, поэтому старым скриптам не нужны изменения- предмет должен существовать в
items.lua, иначе вызов не сработает
Чтобы переключиться, следите за настройкой ox_inventory для ESX и установите опцию пользовательского инвентаря в конфиге es_extended, чтобы ESX знала, какой инвентарь используется. Для добавления предмета способом ox_inventory смотрите how to add items to ox_inventory.
Совет: если вы не хотите редактировать SQL или Lua для каждого нового предмета, Item Creator позволяет вам создавать предметы в игре.
Контрольный список
| Симптом | Исправление |
|---|---|
| Предмет не существует | Добавьте строку в таблицу items или в items.lua с ox_inventory |
| Предмет ничего не делает при использовании | Зарегистрируйте его с помощью ESX.RegisterUsableItem на сервере |
addInventoryItem ничего не дает |
Неправильное имя или игрок не может его нести; проверьте xPlayer.canCarryItem |
| Предмет не удаляется после использования | Обратный вызов должен сам вызвать removeInventoryItem |
getInventoryItem равна nil |
Имя предмета отсутствует в таблице items |
| Несоответствие имен | Имена чувствительны к регистру; используйте точное значение name |
Короткие ответы
Где мне добавить новый предмет в ESX?
В таблице items вашей базы данных с именем, меткой и весом. На сервере, работающем с ox_inventory, предметы определяются в ox_inventory/data/items.lua вместо этого.
Как сделать предмет ESX пригодным для использования?
Зарегистрируйте его на сервере с помощью ESX.RegisterUsableItem('itemname', function(source) ... end). Имя предмета должно совпадать с name в таблице items.
Почему addInventoryItem ничего не делает?
Имя предмета отсутствует в таблице items, игрок не может его нести, или вы использовали имя с другой капитализацией. Проверьте, что предмет существует, и сначала протестируйте с xPlayer.canCarryItem.

