Itens
Adicione, remova, conte e verifique itens em qualquer inventário, registre baús, lojas de scripts e itens usáveis, leia definições de itens e o peso carregado.
Toda chamada de item passa pelo ai-core, nunca pelos exports próprios de um script de inventário. O ai-core encaminha cada chamada ao inventário ativo: o que a configuração Inventory script do painel escolhe, ou o primeiro que estiver rodando quando ela está no automático (ai-inventory, ox_inventory, qb-inventory, tgiann-inventory e os outros da lista de compatibilidade). Quando o dono do servidor troca de inventário, seu script continua funcionando sem alterações.
O que saber:
- Um inventário é identificado por um
InventoryRef: o id de servidor de um jogador (um número) para os bolsos desse jogador, ou um id em texto para qualquer outra coisa (o nome de um baú, a placa de um porta-malas). Veja InventoryRef. - Os nomes de itens são os nomes de itens do inventário (
water,bandage,WEAPON_PISTOL). - Metadata é uma tabela de valores extras numa pilha (um número de série, a durabilidade). Veja ItemMetadata.
- Enquanto nenhum inventário está rodando, cada chamada responde o seu valor de "nada":
false,0, uma lista vazia ounull. - Os baús, lojas e itens usáveis que você registra são guardados pelo ai-core e entregues a cada inventário que fica ativo depois, inclusive depois de um restart do inventário. Registre-os uma vez quando seu script inicia.
AddItem
Dá itens a um inventário.
Lado: Servidor · Espera: não · Lib: inventory.addItem
AddItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:AddItem(source, 'water', 2)Parâmetros
Prop
Type
Retorno
boolean: true quando o inventário adicionou os itens. false quando eles não cabem, o item não existe no inventário, um argumento está errado (count abaixo de 1, nome de item vazio) ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
const TAP = { x: 1206.4, y: -3110.2, z: 5.6 };
onClientCallback("myscript:fillBottle", { guards: [near(TAP, 2)], lock: true }, (source) => {
if (!core.RemoveItem(source, "empty_bottle")) return fail("NO_BOTTLE");
if (!core.AddItem(source, "water")) {
core.AddItem(source, "empty_bottle");
return fail("NO_SPACE");
}
return { ok: true };
});RemoveItem
Tira itens de um inventário.
Lado: Servidor · Espera: não · Lib: inventory.removeItem
RemoveItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:RemoveItem(source, 'lockpick', 1)Parâmetros
Prop
Type
Retorno
boolean: true quando os itens foram tirados. false quando o inventário tem menos (então nenhum é tirado), um argumento está errado ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, minigameFor, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
onClientCallback("myscript:pickLock", { lock: true }, async (source) => {
if (!core.HasItem(source, "lockpick")) return fail("NO_LOCKPICK");
const result = await minigameFor(source, { game: "lockpick", minMs: 1500 });
if (result === "broken") core.RemoveItem(source, "lockpick");
return result === "won" ? { ok: true } : fail("LOCKPICK_FAILED");
});GetItemCount
Quantos de um item um inventário tem.
Lado: Servidor · Espera: não · Lib: inventory.getItemCount
GetItemCount(inv: InventoryRef, item: string, metadata?: ItemMetadata): numberlocal count = exports['ai-core']:GetItemCount(source, 'fish')Parâmetros
Prop
Type
Retorno
number: o total somando todas as pilhas. 0 quando não há nenhum, um argumento está errado ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// O comprador de peixes mostra quanto o jogador receberia.
onClientCallback("myscript:fishQuote", (source) => ({
ok: true,
price: core.GetItemCount(source, "fish") * 25,
}));HasItem
Se um inventário tem pelo menos uma quantidade de um item.
Lado: Servidor · Espera: não · Lib: inventory.hasItem
HasItem(inv: InventoryRef, item: string, count?: number): booleanlocal has = exports['ai-core']:HasItem(source, 'repairkit')Parâmetros
Prop
Type
Retorno
boolean: true quando o inventário tem count ou mais. false quando tem menos, count está abaixo de 1 ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
import { Locale } from "common";
const core = resourceExport("ai-core");
onClientCallback("myscript:repair", { lock: true }, async (source) => {
if (!core.HasItem(source, "repairkit")) return fail("NO_KIT");
if (!(await progressFor(source, { label: Locale("REPAIRING"), duration: 8000 }))) return fail("CANCELLED");
if (!core.RemoveItem(source, "repairkit")) return fail("NO_KIT");
return { ok: true };
});Verifique de novo com a resposta de RemoveItem depois de qualquer coisa que espera (uma barra de progresso, um minigame): o jogador pode ter largado o item nesse meio-tempo.
CanCarryItem
Se itens caberiam num inventário (peso e slots), sem adicioná-los.
Lado: Servidor · Espera: não · Lib: inventory.canCarryItem
CanCarryItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata): booleanlocal fits = exports['ai-core']:CanCarryItem(source, 'water', 5)Parâmetros
Prop
Type
Retorno
boolean: true quando cabem. false quando não cabem, um argumento está errado ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
onClientCallback("myscript:buyWater", { lock: true }, (source) => {
if (!core.CanCarryItem(source, "water", 5)) return fail("NO_SPACE");
if (!core.RemoveMoney(source, "cash", 50, "shop_water")) return fail("NOT_ENOUGH_MONEY");
core.AddItem(source, "water", 5);
return { ok: true };
});GetItems
Cada pilha de um inventário, com rótulos.
Lado: Servidor · Espera: não · Lib: inventory.getItems
GetItems(inv: InventoryRef): InventoryStack[]local stacks = exports['ai-core']:GetItems(source) -- lista de tablesParâmetros
Prop
Type
Retorno
InventoryStack[]: uma entrada por pilha com name, label, count, slot e metadata. Veja InventoryStack. Uma lista vazia para um inventário vazio ou desconhecido, um argumento errado ou nenhum inventário rodando.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Uma loja de penhores lista cada item que o jogador carrega e que ela compra.
const BUYS: Record<string, number> = { gold_ring: 120, rolex: 400 };
onClientCallback("myscript:pawnList", (source) => ({
ok: true,
rows: core.GetItems(source)
.filter((stack) => BUYS[stack.name] !== undefined)
.map((stack) => ({ slot: stack.slot, label: stack.label, count: stack.count, price: BUYS[stack.name] })),
}));ClearInventory
Esvazia um inventário por completo.
Lado: Servidor · Espera: não · Lib: inventory.clearInventory
ClearInventory(inv: InventoryRef): voidexports['ai-core']:ClearInventory(source)Parâmetros
Prop
Type
Retorno
Nada. Um argumento errado ou nenhum inventário rodando não faz nada.
Exemplo
import { addCommand, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
addCommand("clearinv", { help: "Empties a player inventory", params: [{ name: "id", type: "playerId" }], restricted: true }, (_source, args) => {
core.ClearInventory(args.id);
});Isto não pode ser desfeito. Deixe atrás de um comando de admin ou de uma regra de jogo clara (uma entrada na prisão que guarda os itens antes).
RegisterStash
Cria um baú: uma caixa de armazenamento que os jogadores abrem pelo nome. O ai-core o guarda e o registra de novo em cada inventário que fica ativo.
Lado: Servidor · Espera: não · Lib: inventory.registerStash
RegisterStash(name: string, label: string, slots: number, maxWeight: number, jobs?: string[]): voidexports['ai-core']:RegisterStash('police_evidence', 'Evidence', 100, 500000, { 'police' })Parâmetros
Prop
Type
Os padrões se aplicam quando um valor falta ou está errado.
Retorno
Nada. Sem um name em texto a chamada não faz nada. Registrar o mesmo nome de novo substitui o baú.
Exemplo
import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
import { Locale } from "common";
const core = resourceExport("ai-core");
const LOCKER = { x: 474.9, y: -994.7, z: 26.3 };
// Uma vez ao iniciar; o ai-core o entrega aos inventários que iniciarem depois.
core.RegisterStash("police_evidence", Locale("STASH_EVIDENCE"), 100, 500_000, ["police"]);
onClientCallback("myscript:openEvidence", { guards: [near(LOCKER, 2)] }, (source) => {
if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
return core.OpenInventory(source, "police_evidence") ? { ok: true } : fail("STASH_FAILED");
});OpenInventory
Abre um baú, um porta-malas ou o inventário de outro jogador na tela de um jogador, ao lado do dele.
Lado: Servidor · Espera: não · Lib: inventory.openInventory
OpenInventory(source: number, inv: InventoryRef): booleanlocal opened = exports['ai-core']:OpenInventory(source, 'police_evidence')Parâmetros
Prop
Type
Retorno
boolean: true quando o inventário abriu a tela. false quando não conseguiu (baú desconhecido, o jogador não tem inventário), um argumento está errado ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, isNear, coordsOf, resourceExport } from "@aicore-fivem/lib/server";
import { fail, oneArg, readId } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// A polícia revista um jogador algemado parado ao lado.
onClientCallback("myscript:search", { args: oneArg(readId) }, (source, target) => {
if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
if (target === source || !isNear(target, coordsOf(source), 2)) return fail("TOO_FAR");
return core.OpenInventory(source, target) ? { ok: true } : fail("SEARCH_FAILED");
});O inventário não faz nenhuma verificação de distância ou permissão aqui. Verifique o emprego, a distância e o estado do alvo você mesmo antes de chamar.
RegisterShop
Cria uma loja de script: uma lista de itens com preços que seu script abre para um jogador (um arsenal, uma máquina de venda). O inventário desenha a loja e cobra o pagamento do seu próprio jeito (dinheiro vivo, depois banco). O ai-core a guarda e a entrega a cada inventário que fica ativo.
Lado: Servidor · Espera: não · Lib: inventory.registerShop
RegisterShop(name: string, label: string, items: ShopProduct[]): voidexports['ai-core']:RegisterShop('police_armoury', 'Armoury', { { name = 'bandage', price = 0 } })Parâmetros
Prop
Type
Veja ShopProduct.
Retorno
Nada. Sem um name em texto ou sem nenhum produto válido a chamada não faz nada. Registrar o mesmo nome de novo substitui a loja.
Exemplo
import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
import { Locale } from "common";
const core = resourceExport("ai-core");
const ARMOURY = { x: 482.6, y: -995.2, z: 30.7 };
core.RegisterShop("police_armoury", Locale("SHOP_ARMOURY"), [
{ name: "WEAPON_STUNGUN", price: 0 },
{ name: "bandage", price: 10 },
]);
onClientCallback("myscript:armoury", { guards: [near(ARMOURY, 2)] }, (source) => {
if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
return core.OpenShop(source, "police_armoury") ? { ok: true } : fail("SHOP_FAILED");
});OpenShop
Abre uma loja registrada com RegisterShop na tela de um jogador.
Lado: Servidor · Espera: não · Lib: inventory.openShop
OpenShop(source: number, name: string): booleanlocal opened = exports['ai-core']:OpenShop(source, 'police_armoury')Parâmetros
Prop
Type
Retorno
boolean: true quando a loja abriu. false quando nenhuma loja tem esse nome, o inventário ativo não tem lojas de scripts, não conseguiu abrir ou nenhum inventário está rodando.
Exemplo
Veja o exemplo de RegisterShop acima: registre uma vez ao iniciar e depois abra após as suas próprias verificações de emprego e distância.
Como OpenInventory, isto não faz nenhuma verificação de distância ou acesso. Verifique-as antes.
RegisterUsableItem
Torna um item usável: quando um jogador o usa no inventário, sua função roda. O ai-core guarda a função, então ela funciona com inventários que iniciam depois e sobrevive a um restart do inventário.
Lado: Servidor · Espera: não · Lib: inventory.registerUsableItem
RegisterUsableItem(name: string, handler: UsableItemHandler): void
// UsableItemHandler = (source: number, item: UsedItem) => unknownexports['ai-core']:RegisterUsableItem('bandage', function(source, item) end)Parâmetros
Prop
Type
Veja UsableItemHandler e UsedItem.
Retorno
Nada. Sem um name em texto ou uma função a chamada não faz nada. Uma segunda chamada para o mesmo item substitui o handler.
O que acontece com o item depois do uso depende do inventário: inventários que tiram um item usado eles mesmos (o ai-inventory tira a quantidade de consume do item) o mantêm quando seu handler retorna false; outros inventários seguem as próprias configurações de itens, então ali remova o item você mesmo quando precisar.
Exemplo
import { progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
core.RegisterUsableItem("bandage", (source) => {
// O handler precisa responder na hora; a parte cronometrada roda sozinha.
void (async () => {
if (!(await progressFor(source, { label: Locale("BANDAGING"), duration: 4000 }))) return;
if (!core.RemoveItem(source, "bandage")) return;
emitNet("myscript:client:heal", source, 25); // seu script de cliente adiciona a vida
})();
return false; // mantém o item: ele é removido acima quando a barra termina
});Um uso também dispara o evento de servidor ai-core:itemUsed (src, name, status), que efeitos de itens como fome e sede seguem. Veja Eventos e estado.
GetItemDefinition
Um item como o inventário ativo o define: rótulo, peso, se empilha, imagem.
Lado: Servidor · Espera: não · Lib: inventory.getItemDefinition
GetItemDefinition(name: string): ItemDefinition | nulllocal def = exports['ai-core']:GetItemDefinition('water') -- table ou nilParâmetros
Prop
Type
Retorno
ItemDefinition | null: o item com name, label, weight, unique, close, description e image quando o inventário tem uma. Veja ItemDefinition. null para um item desconhecido, um nome vazio ou nenhum inventário rodando.
Exemplo
import { notify, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
/** "You received 2x Water" with the inventory's own label. */
export function giveWithNotice(source: number, item: string, count: number): void {
if (!core.AddItem(source, item, count)) return;
const label = core.GetItemDefinition(item)?.label ?? item;
notify(source, Locale("NOTIFY_RECEIVED", count, label), "success");
}GetItemDefinitions
Cada item que o inventário ativo define, indexado pelo nome. Use raramente (montar uma lista uma vez); para um item use GetItemDefinition.
Lado: Servidor · Espera: não · Lib: nenhuma
GetItemDefinitions(): Record<string, ItemDefinition>local items = exports['ai-core']:GetItemDefinitions() -- table indexada pelo nome do itemParâmetros
Nenhum.
Retorno
Record<string, ItemDefinition>: cada item. Uma tabela vazia enquanto nenhum inventário está rodando.
Exemplo
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Warns at start about items in your config that the inventory does not know. */
export function checkItems(names: string[]): void {
const known = core.GetItemDefinitions();
for (const name of names) if (!known[name]) console.log(`unknown item: ${name}`);
}Faça esse tipo de verificação depois que o inventário iniciou: logo depois de um start do servidor o inventário pode ainda não estar rodando e a tabela fica vazia.
GetInventoryWeight
O que um jogador carrega e pode carregar, por peso.
Lado: Servidor · Espera: não · Lib: nenhuma
GetInventoryWeight(source: number): { weight: number; maxWeight: number } | nulllocal w = exports['ai-core']:GetInventoryWeight(source) -- { weight, maxWeight } ou nilParâmetros
Prop
Type
Retorno
{ weight, maxWeight } | null: peso carregado e o limite, em gramas. null quando o inventário ativo não os informa, o jogador não tem inventário carregado ou nenhum inventário está rodando.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
onClientCallback("myscript:weight", (source) => {
const w = core.GetInventoryWeight(source);
return { ok: true, free: w ? w.maxWeight - w.weight : null };
});UseItem
Roda o handler registrado para um item, como se o jogador o tivesse usado. A ponte ESX / QB do ai-core o chama (a partir de ESX.UseItem e do CanUseItem do QB); um script normal não tem motivo para isso.
Lado: Servidor · Espera: não · Lib: nenhuma (só a ponte)
UseItem(source: number, name: string, item?: unknown): unknownlocal result = exports['ai-core']:UseItem(source, 'bandage', stack)Parâmetros
Prop
Type
Retorno
unknown: o que o handler retornou. false quando nenhum handler está registrado, os argumentos estão errados ou o handler lançou um erro (registrado no log).
Exemplo
Sem exemplo: os inventários e a ponte o chamam. Para reagir a um uso, registre o item com RegisterUsableItem.
IsUsableItem
Se um handler está registrado para um item. A ponte do ai-core usa isto.
Lado: Servidor · Espera: não · Lib: nenhuma (só a ponte)
IsUsableItem(name: string): booleanlocal usable = exports['ai-core']:IsUsableItem('bandage')Parâmetros
Prop
Type
Retorno
boolean: true quando algum recurso registrou o item com RegisterUsableItem. false caso contrário.
Exemplo
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Item tooltips show "Use" only for usable items. */
export function canUse(item: string): boolean {
return core.IsUsableItem(item);
}