Objets
Ajouter, retirer, compter et vérifier des objets dans n’importe quel inventaire, enregistrer des coffres, des magasins de script et des objets utilisables, lire les définitions d’objets et le poids porté.
Chaque appel d’objet passe par ai-core, jamais par les exports propres à un script d’inventaire. ai-core transmet chaque appel à l’inventaire actif : celui que choisit le réglage Inventory script du panneau, ou le premier qui tourne quand il est en automatique (ai-inventory, ox_inventory, qb-inventory, tgiann-inventory et les autres de la liste de compatibilité). Quand le propriétaire du serveur change d’inventaire, votre script continue de fonctionner sans modification.
Ce qu’il faut savoir :
- Un inventaire est désigné par un
InventoryRef: l’id serveur d’un joueur (un nombre) pour les poches de ce joueur, ou un id texte pour tout le reste (un nom de coffre, une plaque de coffre de véhicule). Voir InventoryRef. - Les noms d’objets sont les noms d’objets de l’inventaire (
water,bandage,WEAPON_PISTOL). - Les métadonnées sont une table de valeurs supplémentaires sur une pile (un numéro de série, une durabilité). Voir ItemMetadata.
- Tant qu’aucun inventaire ne tourne, chaque appel répond sa valeur « rien » :
false,0, une liste vide ounull. - Les coffres, magasins et objets utilisables que vous enregistrez sont gardés par ai-core et transmis à chaque inventaire qui devient actif plus tard, y compris après un redémarrage de l’inventaire. Enregistrez-les une fois au démarrage de votre script.
AddItem
Donne des objets à un inventaire.
Côté : Serveur · Attend : non · Lib : inventory.addItem
AddItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:AddItem(source, 'water', 2)Paramètres
Prop
Type
Retour
boolean : true quand l’inventaire a ajouté les objets. false quand ils ne tiennent pas, que l’objet n’existe pas dans l’inventaire, qu’un argument est incorrect (count inférieur à 1, nom d’objet vide) ou qu’aucun inventaire ne tourne.
Exemple
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
Retire des objets d’un inventaire.
Côté : Serveur · Attend : non · Lib : inventory.removeItem
RemoveItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata, slot?: number): booleanlocal ok = exports['ai-core']:RemoveItem(source, 'lockpick', 1)Paramètres
Prop
Type
Retour
boolean : true quand les objets ont été retirés. false quand l’inventaire en contient moins (aucun n’est alors retiré), qu’un argument est incorrect ou qu’aucun inventaire ne tourne.
Exemple
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
Combien d’un objet contient un inventaire.
Côté : Serveur · Attend : non · Lib : inventory.getItemCount
GetItemCount(inv: InventoryRef, item: string, metadata?: ItemMetadata): numberlocal count = exports['ai-core']:GetItemCount(source, 'fish')Paramètres
Prop
Type
Retour
number : le total sur toutes les piles. 0 quand il n’y en a aucune, qu’un argument est incorrect ou qu’aucun inventaire ne tourne.
Exemple
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// L’acheteur de poisson montre combien le joueur recevrait.
onClientCallback("myscript:fishQuote", (source) => ({
ok: true,
price: core.GetItemCount(source, "fish") * 25,
}));HasItem
Indique si un inventaire contient au moins une quantité d’un objet.
Côté : Serveur · Attend : non · Lib : inventory.hasItem
HasItem(inv: InventoryRef, item: string, count?: number): booleanlocal has = exports['ai-core']:HasItem(source, 'repairkit')Paramètres
Prop
Type
Retour
boolean : true quand l’inventaire en contient count ou plus. false quand il en contient moins, que count est inférieur à 1, ou qu’aucun inventaire ne tourne.
Exemple
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 };
});Revérifiez avec la réponse de RemoveItem après tout ce qui attend (une barre de progression, un mini-jeu) : le joueur a pu jeter l’objet entre-temps.
CanCarryItem
Indique si des objets tiendraient dans un inventaire (poids et emplacements), sans les ajouter.
Côté : Serveur · Attend : non · Lib : inventory.canCarryItem
CanCarryItem(inv: InventoryRef, item: string, count?: number, metadata?: ItemMetadata): booleanlocal fits = exports['ai-core']:CanCarryItem(source, 'water', 5)Paramètres
Prop
Type
Retour
boolean : true quand ils tiennent. false quand ils ne tiennent pas, qu’un argument est incorrect ou qu’aucun inventaire ne tourne.
Exemple
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
Chaque pile d’un inventaire, avec libellés.
Côté : Serveur · Attend : non · Lib : inventory.getItems
GetItems(inv: InventoryRef): InventoryStack[]local stacks = exports['ai-core']:GetItems(source) -- liste de tablesParamètres
Prop
Type
Retour
InventoryStack[] : une entrée par pile avec name, label, count, slot et metadata. Voir InventoryStack. Une liste vide pour un inventaire vide ou inconnu, un argument incorrect ou aucun inventaire en cours.
Exemple
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Un prêteur sur gages liste chaque objet que porte le joueur et qu’il rachète.
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
Vide complètement un inventaire.
Côté : Serveur · Attend : non · Lib : inventory.clearInventory
ClearInventory(inv: InventoryRef): voidexports['ai-core']:ClearInventory(source)Paramètres
Prop
Type
Retour
Rien. Un argument incorrect ou l’absence d’inventaire en cours ne fait rien.
Exemple
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);
});Ceci est irréversible. Gardez-le derrière une commande d’admin ou une règle de jeu claire (une entrée en prison qui stocke d’abord les objets).
RegisterStash
Crée un coffre : une boîte de stockage que les joueurs ouvrent par son nom. ai-core le garde et l’enregistre de nouveau auprès de chaque inventaire qui devient actif.
Côté : Serveur · Attend : non · Lib : inventory.registerStash
RegisterStash(name: string, label: string, slots: number, maxWeight: number, jobs?: string[]): voidexports['ai-core']:RegisterStash('police_evidence', 'Evidence', 100, 500000, { 'police' })Paramètres
Prop
Type
Les valeurs par défaut s’appliquent quand une valeur manque ou est incorrecte.
Retour
Rien. Sans name texte, l’appel ne fait rien. Enregistrer de nouveau le même nom remplace le coffre.
Exemple
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 };
// Une fois au démarrage ; ai-core le transmet aux inventaires qui démarrent plus tard.
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
Ouvre un coffre, un coffre de véhicule ou l’inventaire d’un autre joueur sur l’écran d’un joueur, à côté du sien.
Côté : Serveur · Attend : non · Lib : inventory.openInventory
OpenInventory(source: number, inv: InventoryRef): booleanlocal opened = exports['ai-core']:OpenInventory(source, 'police_evidence')Paramètres
Prop
Type
Retour
boolean : true quand l’inventaire a ouvert l’écran. false quand il n’a pas pu (coffre inconnu, le joueur n’a pas d’inventaire), qu’un argument est incorrect ou qu’aucun inventaire ne tourne.
Exemple
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 police fouille un joueur menotté debout à côté d’elle.
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");
});L’inventaire ne fait ici aucune vérification de distance ni de permission. Vérifiez vous-même le métier, la distance et l’état de la cible avant de l’appeler.
RegisterShop
Crée un magasin de script : une liste d’objets avec des prix que votre script ouvre pour un joueur (une armurerie, un distributeur automatique). L’inventaire dessine le magasin et prend le paiement à sa façon (liquide, puis banque). ai-core le garde et le transmet à chaque inventaire qui devient actif.
Côté : Serveur · Attend : non · Lib : inventory.registerShop
RegisterShop(name: string, label: string, items: ShopProduct[]): voidexports['ai-core']:RegisterShop('police_armoury', 'Armoury', { { name = 'bandage', price = 0 } })Paramètres
Prop
Type
Voir ShopProduct.
Retour
Rien. Sans name texte ou sans produit valide, l’appel ne fait rien. Enregistrer de nouveau le même nom remplace le magasin.
Exemple
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
Ouvre sur l’écran d’un joueur un magasin enregistré avec RegisterShop.
Côté : Serveur · Attend : non · Lib : inventory.openShop
OpenShop(source: number, name: string): booleanlocal opened = exports['ai-core']:OpenShop(source, 'police_armoury')Paramètres
Prop
Type
Retour
boolean : true quand le magasin s’est ouvert. false quand aucun magasin ne porte ce nom, que l’inventaire actif n’a pas de magasins de script, qu’il n’a pas pu l’ouvrir, ou qu’aucun inventaire ne tourne.
Exemple
Voir l’exemple de RegisterShop ci-dessus : enregistrez une fois au démarrage, puis ouvrez après vos propres vérifications de métier et de distance.
Comme OpenInventory, ceci ne fait aucune vérification de distance ni d’accès. Vérifiez-les d’abord.
RegisterUsableItem
Rend un objet utilisable : quand un joueur l’utilise dans l’inventaire, votre fonction s’exécute. ai-core garde la fonction, elle fonctionne donc avec les inventaires qui démarrent plus tard et survit à un redémarrage de l’inventaire.
Côté : Serveur · Attend : non · Lib : inventory.registerUsableItem
RegisterUsableItem(name: string, handler: UsableItemHandler): void
// UsableItemHandler = (source: number, item: UsedItem) => unknownexports['ai-core']:RegisterUsableItem('bandage', function(source, item) end)Paramètres
Prop
Type
Voir UsableItemHandler et UsedItem.
Retour
Rien. Sans name texte ou sans fonction, l’appel ne fait rien. Un second appel pour le même objet remplace le handler.
Ce qu’il advient de l’objet après utilisation dépend de l’inventaire : les inventaires qui retirent eux-mêmes un objet utilisé (ai-inventory retire la quantité consume de l’objet) le gardent quand votre handler renvoie false ; les autres inventaires suivent leurs propres réglages d’objets, retirez donc l’objet vous-même là où c’est nécessaire.
Exemple
import { progressFor, resourceExport } from "@aicore-fivem/lib/server";
import { Locale } from "common";
const core = resourceExport("ai-core");
core.RegisterUsableItem("bandage", (source) => {
// Le handler doit répondre tout de suite ; la partie temporisée tourne d’elle-même.
void (async () => {
if (!(await progressFor(source, { label: Locale("BANDAGING"), duration: 4000 }))) return;
if (!core.RemoveItem(source, "bandage")) return;
emitNet("myscript:client:heal", source, 25); // votre script client ajoute la santé
})();
return false; // le garder : il est retiré plus haut une fois la barre terminée
});Une utilisation déclenche aussi l’événement serveur ai-core:itemUsed (src, name, status), que suivent les effets d’objets comme la faim et la soif. Voir Événements et état.
GetItemDefinition
Un objet tel que le définit l’inventaire actif : libellé, poids, s’il s’empile, image.
Côté : Serveur · Attend : non · Lib : inventory.getItemDefinition
GetItemDefinition(name: string): ItemDefinition | nulllocal def = exports['ai-core']:GetItemDefinition('water') -- table ou nilParamètres
Prop
Type
Retour
ItemDefinition | null : l’objet avec name, label, weight, unique, close, description et image quand l’inventaire en a une. Voir ItemDefinition. null pour un objet inconnu, un nom vide ou aucun inventaire en cours.
Exemple
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
Chaque objet que définit l’inventaire actif, indexé par nom. Utilisez-le rarement (construire une liste une fois) ; pour un seul objet, utilisez GetItemDefinition.
Côté : Serveur · Attend : non · Lib : aucune
GetItemDefinitions(): Record<string, ItemDefinition>local items = exports['ai-core']:GetItemDefinitions() -- table indexée par nom d’objetParamètres
Aucun.
Retour
Record<string, ItemDefinition> : chaque objet. Une table vide tant qu’aucun inventaire ne tourne.
Exemple
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}`);
}Faites une telle vérification après le démarrage de l’inventaire : juste après un démarrage du serveur, l’inventaire peut ne pas encore tourner et la table est vide.
GetInventoryWeight
Ce que porte un joueur et ce qu’il peut porter, en poids.
Côté : Serveur · Attend : non · Lib : aucune
GetInventoryWeight(source: number): { weight: number; maxWeight: number } | nulllocal w = exports['ai-core']:GetInventoryWeight(source) -- { weight, maxWeight } ou nilParamètres
Prop
Type
Retour
{ weight, maxWeight } | null : le poids porté et la limite, en grammes. null quand l’inventaire actif ne les donne pas, que le joueur n’a pas d’inventaire chargé ou qu’aucun inventaire ne tourne.
Exemple
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
Exécute le handler enregistré pour un objet, comme si le joueur l’avait utilisé. Le pont ESX / QB d’ai-core l’appelle (depuis ESX.UseItem et CanUseItem de QB) ; un script normal n’a aucune raison de le faire.
Côté : Serveur · Attend : non · Lib : aucune (pont uniquement)
UseItem(source: number, name: string, item?: unknown): unknownlocal result = exports['ai-core']:UseItem(source, 'bandage', stack)Paramètres
Prop
Type
Retour
unknown : ce que le handler a renvoyé. false quand aucun handler n’est enregistré, que les arguments sont incorrects ou que le handler a levé une erreur (elle est enregistrée dans le log).
Exemple
Pas d’exemple : les inventaires et le pont l’appellent. Pour réagir à une utilisation, enregistrez l’objet avec RegisterUsableItem.
IsUsableItem
Indique si un handler est enregistré pour un objet. Le pont d’ai-core l’utilise.
Côté : Serveur · Attend : non · Lib : aucune (pont uniquement)
IsUsableItem(name: string): booleanlocal usable = exports['ai-core']:IsUsableItem('bandage')Paramètres
Prop
Type
Retour
boolean : true quand une ressource a enregistré l’objet avec RegisterUsableItem. false sinon.
Exemple
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);
}