Objetos
Añade, quita, cuenta y comprueba objetos en cualquier inventario, registra alijos, tiendas de scripts y objetos usables, lee definiciones de objetos y el peso que se lleva.
Cada llamada de objetos pasa por ai-core, nunca por los exports propios de un script de inventario. ai-core reenvía cada llamada al inventario activo: el que elige el ajuste Inventory script (script de inventario) del panel, o el primero que esté en marcha cuando está en automático (ai-inventory, ox_inventory, qb-inventory, tgiann-inventory y los demás de la lista de compatibilidad). Cuando el dueño del servidor cambia de inventario, tu script sigue funcionando sin cambios.
Lo que debes saber:
- Un inventario se nombra con un
InventoryRef: el id de servidor de un jugador (un número) para los bolsillos de ese jugador, o un id de texto para cualquier otra cosa (un nombre de alijo, la matrícula de un maletero). Consulta InventoryRef. - Los nombres de objetos son los nombres de objeto del inventario (
water,bandage,WEAPON_PISTOL). - Los metadatos son una tabla de valores extra en una pila (un número de serie, la durabilidad). Consulta ItemMetadata.
- Mientras no hay ningún inventario en marcha, cada llamada responde su valor de "nada":
false,0, una lista vacía onull. - Los alijos, tiendas y objetos usables que registras los guarda ai-core y se los entrega a cada inventario que se active después, también tras reiniciar un inventario. Regístralos una vez cuando se inicie tu script.
AddItem
Da objetos a un inventario.
Lado: Servidor · Espera: no · 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
Devuelve
boolean: true cuando el inventario añadió los objetos. false cuando no caben, el objeto no existe en el inventario, un argumento es erróneo (count menor que 1, nombre de objeto vacío) o no hay ningún inventario en marcha.
Ejemplo
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
Quita objetos de un inventario.
Lado: Servidor · Espera: no · 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
Devuelve
boolean: true cuando se quitaron los objetos. false cuando el inventario tiene menos (entonces no se quita ninguno), un argumento es erróneo o no hay ningún inventario en marcha.
Ejemplo
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
Cuántas unidades de un objeto tiene un inventario.
Lado: Servidor · Espera: no · Lib: inventory.getItemCount
GetItemCount(inv: InventoryRef, item: string, metadata?: ItemMetadata): numberlocal count = exports['ai-core']:GetItemCount(source, 'fish')Parámetros
Prop
Type
Devuelve
number: el total de todas las pilas. 0 cuando no hay ninguno, un argumento es erróneo o no hay ningún inventario en marcha.
Ejemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// El comprador de pescado muestra cuánto recibiría el jugador.
onClientCallback("myscript:fishQuote", (source) => ({
ok: true,
price: core.GetItemCount(source, "fish") * 25,
}));HasItem
Si un inventario tiene al menos cierta cantidad de un objeto.
Lado: Servidor · Espera: no · Lib: inventory.hasItem
HasItem(inv: InventoryRef, item: string, count?: number): booleanlocal has = exports['ai-core']:HasItem(source, 'repairkit')Parámetros
Prop
Type
Devuelve
boolean: true cuando el inventario tiene count o más. false cuando tiene menos, count es menor que 1 o no hay ningún inventario en marcha.
Ejemplo
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 };
});Vuelve a comprobarlo con la respuesta de RemoveItem después de cualquier cosa que espere (una barra de progreso, un minijuego): el jugador puede haber tirado el objeto mientras tanto.
CanCarryItem
Si unos objetos cabrían en un inventario (peso y ranuras), sin añadirlos.
Lado: Servidor · Espera: no · 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
Devuelve
boolean: true cuando caben. false cuando no caben, un argumento es erróneo o no hay ningún inventario en marcha.
Ejemplo
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 pila de un inventario, con etiquetas.
Lado: Servidor · Espera: no · Lib: inventory.getItems
GetItems(inv: InventoryRef): InventoryStack[]local stacks = exports['ai-core']:GetItems(source) -- lista de tablasParámetros
Prop
Type
Devuelve
InventoryStack[]: una entrada por pila con name, label, count, slot y metadata. Consulta InventoryStack. Una lista vacía para un inventario vacío o desconocido, un argumento erróneo o si no hay ningún inventario en marcha.
Ejemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Una casa de empeños lista cada objeto que lleva el jugador y que ella 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
Vacía un inventario por completo.
Lado: Servidor · Espera: no · Lib: inventory.clearInventory
ClearInventory(inv: InventoryRef): voidexports['ai-core']:ClearInventory(source)Parámetros
Prop
Type
Devuelve
Nada. Un argumento erróneo o la falta de un inventario en marcha no hace nada.
Ejemplo
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);
});Esto no se puede deshacer. Ponlo detrás de un comando de admin o de una regla de juego clara (un ingreso en prisión que antes guarda los objetos).
RegisterStash
Crea un alijo: una caja de almacenamiento que los jugadores abren por su nombre. ai-core lo guarda y lo vuelve a registrar en cada inventario que se active.
Lado: Servidor · Espera: no · 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
Los valores por defecto se aplican cuando un valor falta o es erróneo.
Devuelve
Nada. Sin un name de texto la llamada no hace nada. Registrar de nuevo el mismo nombre reemplaza el alijo.
Ejemplo
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 };
// Una vez al iniciar; ai-core se lo entrega a los inventarios que se inicien más tarde.
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 un alijo, un maletero o el inventario de otro jugador en la pantalla de un jugador, junto al suyo propio.
Lado: Servidor · Espera: no · Lib: inventory.openInventory
OpenInventory(source: number, inv: InventoryRef): booleanlocal opened = exports['ai-core']:OpenInventory(source, 'police_evidence')Parámetros
Prop
Type
Devuelve
boolean: true cuando el inventario abrió la pantalla. false cuando no pudo (alijo desconocido, el jugador no tiene inventario), un argumento es erróneo o no hay ningún inventario en marcha.
Ejemplo
import { onClientCallback, isNear, coordsOf, resourceExport } from "@aicore-fivem/lib/server";
import { fail, oneArg, readId } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// La policía cachea a un jugador esposado que tiene al 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");
});Aquí el inventario no comprueba ni la distancia ni los permisos. Comprueba tú el trabajo, la distancia y el estado del objetivo antes de llamarlo.
RegisterShop
Crea una tienda de script: una lista de objetos con precios que tu script abre para un jugador (una armería, una máquina expendedora). El inventario dibuja la tienda y cobra a su manera (efectivo y luego banco). ai-core la guarda y se la entrega a cada inventario que se active.
Lado: Servidor · Espera: no · 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
Consulta ShopProduct.
Devuelve
Nada. Sin un name de texto o sin ningún producto válido la llamada no hace nada. Registrar de nuevo el mismo nombre reemplaza la tienda.
Ejemplo
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 en la pantalla de un jugador una tienda registrada con RegisterShop.
Lado: Servidor · Espera: no · Lib: inventory.openShop
OpenShop(source: number, name: string): booleanlocal opened = exports['ai-core']:OpenShop(source, 'police_armoury')Parámetros
Prop
Type
Devuelve
boolean: true cuando se abrió la tienda. false cuando ninguna tienda tiene ese nombre, el inventario activo no tiene tiendas de scripts, no pudo abrirla o no hay ningún inventario en marcha.
Ejemplo
Consulta el ejemplo de RegisterShop de arriba: regístrala una vez al iniciar y ábrela después de tus propias comprobaciones de trabajo y distancia.
Igual que OpenInventory, esto no comprueba la distancia ni el acceso. Compruébalos antes.
RegisterUsableItem
Hace usable un objeto: cuando un jugador lo usa en el inventario, se ejecuta tu función. ai-core guarda la función, así que funciona con inventarios que se inicien más tarde y sobrevive a un reinicio del inventario.
Lado: Servidor · Espera: no · 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
Consulta UsableItemHandler y UsedItem.
Devuelve
Nada. Sin un name de texto o una función la llamada no hace nada. Una segunda llamada para el mismo objeto reemplaza el handler.
Lo que le pasa al objeto tras usarlo depende del inventario: los inventarios que retiran ellos mismos el objeto usado (ai-inventory retira la cantidad consume del objeto) lo conservan cuando tu handler devuelve false; los demás inventarios siguen sus propios ajustes de objeto, así que ahí quita tú el objeto cuando haga falta.
Ejemplo
import { progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
core.RegisterUsableItem("bandage", (source) => {
// El handler debe responder al momento; la parte temporizada corre por su cuenta.
void (async () => {
if (!(await progressFor(source, { label: Locale("BANDAGING"), duration: 4000 }))) return;
if (!core.RemoveItem(source, "bandage")) return;
emitNet("myscript:client:heal", source, 25); // tu script de cliente añade la salud
})();
return false; // se conserva: se quita arriba cuando termina la barra
});Un uso también dispara el evento de servidor ai-core:itemUsed (src, name, status), que siguen efectos de objetos como el hambre y la sed. Consulta Eventos y estado.
GetItemDefinition
Un objeto tal como lo define el inventario activo: etiqueta, peso, si se apila, imagen.
Lado: Servidor · Espera: no · Lib: inventory.getItemDefinition
GetItemDefinition(name: string): ItemDefinition | nulllocal def = exports['ai-core']:GetItemDefinition('water') -- table o nilParámetros
Prop
Type
Devuelve
ItemDefinition | null: el objeto con name, label, weight, unique, close, description e image cuando el inventario tiene una. Consulta ItemDefinition. null para un objeto desconocido, un nombre vacío o si no hay ningún inventario en marcha.
Ejemplo
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 objeto que define el inventario activo, con el nombre como clave. Úsalo poco (construir una lista una vez); para un solo objeto usa GetItemDefinition.
Lado: Servidor · Espera: no · Lib: ninguna
GetItemDefinitions(): Record<string, ItemDefinition>local items = exports['ai-core']:GetItemDefinitions() -- tabla con el nombre del objeto como claveParámetros
Ninguno.
Devuelve
Record<string, ItemDefinition>: cada objeto. Una tabla vacía mientras no hay ningún inventario en marcha.
Ejemplo
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}`);
}Haz una comprobación así después de que se inicie el inventario: justo tras arrancar el servidor puede que el inventario aún no esté en marcha y la tabla esté vacía.
GetInventoryWeight
Lo que lleva un jugador y lo que puede llevar, por peso.
Lado: Servidor · Espera: no · Lib: ninguna
GetInventoryWeight(source: number): { weight: number; maxWeight: number } | nulllocal w = exports['ai-core']:GetInventoryWeight(source) -- { weight, maxWeight } o nilParámetros
Prop
Type
Devuelve
{ weight, maxWeight } | null: el peso que lleva y el límite, en gramos. null cuando el inventario activo no los indica, el jugador no tiene un inventario cargado o no hay ningún inventario en marcha.
Ejemplo
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
Ejecuta el handler registrado para un objeto, como si el jugador lo usara. Lo llama el puente de ESX / QB de ai-core (desde ESX.UseItem y el CanUseItem de QB); un script normal no tiene motivo para hacerlo.
Lado: Servidor · Espera: no · Lib: ninguna (solo el puente)
UseItem(source: number, name: string, item?: unknown): unknownlocal result = exports['ai-core']:UseItem(source, 'bandage', stack)Parámetros
Prop
Type
Devuelve
unknown: lo que devolvió el handler. false cuando no hay ningún handler registrado, los argumentos son erróneos o el handler lanzó un error (queda en el log).
Ejemplo
Sin ejemplo: lo llaman los inventarios y el puente. Para reaccionar a un uso, registra el objeto con RegisterUsableItem.
IsUsableItem
Si hay un handler registrado para un objeto. Lo usa el puente de ai-core.
Lado: Servidor · Espera: no · Lib: ninguna (solo el puente)
IsUsableItem(name: string): booleanlocal usable = exports['ai-core']:IsUsableItem('bandage')Parámetros
Prop
Type
Devuelve
boolean: true cuando algún recurso registró el objeto con RegisterUsableItem. false en otro caso.
Ejemplo
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);
}