AI Core
Référence de l’APIAI Core : exports serveur

Métiers et gangs

Lire et modifier les métiers, gangs, grades et le service d’un personnage, compter les joueurs en service, heures de pointe, lire les définitions des métiers et des gangs.

Un personnage peut avoir plusieurs métiers et plusieurs gangs (jusqu’aux réglages Most jobs per character et Most gangs per character du panneau). Au plus un métier est en service à la fois, et seul ce métier verse un salaire. Au plus un gang est actif. Les métiers et les gangs, avec leurs grades, sont définis dans le panneau d’administration (sections Jobs et Gangs).

Un grade est une position dans la liste des grades du métier, comptée à partir de 0 : le grade 0 est la première ligne du panneau, le grade 1 la deuxième, et ainsi de suite.

Chaque changement déclenche un événement serveur (ai-core:jobsChanged, ai-core:dutyChanged, ai-core:gangsChanged, ai-core:activeGangChanged) et atteint le propre jeu du joueur. Les ressources qui ont besoin des métiers de nombreux joueurs suivent ces événements via le miroir online de la lib au lieu d’appeler les exports ci-dessous pour chaque joueur. Voir Événements et état.

GetJobs

Chaque appartenance à un métier du personnage d’un joueur.

Côté : Serveur · Attend : non · Lib : online.jobs(source) lit la même chose depuis le miroir de la lib

Signature
GetJobs(src: number): JobMembership[] | null
Lua
local jobs = exports['ai-core']:GetJobs(source) -- liste de { job, grade } ou nil

Paramètres

Prop

Type

Retour

JobMembership[] | null : un { job, grade } par métier (JobMembership). Une liste vide quand le personnage n’a pas de métier (le métier chômeur du panneau n’est jamais stocké). null quand le joueur n’a pas de personnage chargé.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// Un écran de pôle emploi liste les métiers du joueur avec leurs libellés.
onClientCallback("myscript:myJobs", (source) => {
  const jobs = core.GetJobs(source);
  if (!jobs) return fail("NO_CHARACTER");
  return {
    ok: true,
    jobs: jobs.map(({ job, grade }) => ({
      job,
      label: core.GetJobDefinition(job)?.label ?? job,
      grade,
    })),
  };
});

GetCurrentJob

Le métier que les autres scripts doivent traiter comme « le » métier du joueur : le métier en service, sinon le dernier métier où le joueur était en service, sinon le premier métier, sinon le métier chômeur du panneau. Les scripts ESX et QB voient ce métier via le pont.

Côté : Serveur · Attend : non · Lib : aucune

Signature
GetCurrentJob(src: number): JobMembership | null
Lua
local job = exports['ai-core']:GetCurrentJob(source) -- { job, grade } ou nil

Paramètres

Prop

Type

Retour

JobMembership | null : { job, grade }. Pour un personnage sans métier, c’est le métier chômeur (réglage du panneau, unemployed par défaut) au grade 0. null seulement quand le joueur n’a pas de personnage chargé.

Exemple

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("job", { help: "Shows a player job", params: [{ name: "id", type: "playerId" }], restricted: true }, (_source, args) => {
  const job = core.GetCurrentJob(args.id);
  if (job) console.log(`${job.job} grade ${job.grade}`);
});

GetDutyJob

Le métier pour lequel le joueur est en service en ce moment. Utilisez-le pour chaque vérification du type « seule la police en service peut faire ceci ».

Côté : Serveur · Attend : non · Lib : online.dutyJob(source) lit la même chose depuis le miroir de la lib

Signature
GetDutyJob(src: number): string | null
Lua
local job = exports['ai-core']:GetDutyJob(source) -- nom du métier ou nil

Paramètres

Prop

Type

Retour

string | null : le nom du métier. null quand le joueur est hors service ou n’a pas de personnage chargé.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:openArmory", (source) => {
  if (core.GetDutyJob(source) !== "police") return fail("NOT_POLICE");
  return { ok: true };
});

SetDuty

Met un joueur en service pour l’un de ses métiers (et hors service dans tous les autres), ou hors service.

Côté : Serveur · Attend : non · Lib : aucune

Signature
SetDuty(src: number, job: string | null): boolean
Lua
local ok = exports['ai-core']:SetDuty(source, 'police') -- nil = hors service

Paramètres

Prop

Type

Retour

boolean : true quand le joueur est maintenant en service pour job (ou hors service pour null), aussi quand rien n’a dû changer. false quand le joueur n’a pas job ou n’a pas de personnage chargé.

Exemple

import { onClientCallback, resourceExport, near } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");
const LOCKER_ROOM = { x: 452.3, y: -993.2, z: 30.7 };

// Un interrupteur de service dans le vestiaire du commissariat.
onClientCallback("myscript:toggleDuty", { guards: [near(LOCKER_ROOM, 3)] }, (source) => {
  const onDuty = core.GetDutyJob(source) === "police";
  return core.SetDuty(source, onDuty ? null : "police") ? { ok: true, onDuty: !onDuty } : fail("NOT_POLICE");
});

Le service n’est pas enregistré : un joueur qui se connecte est hors service, sauf si le réglage Keep duty after rejoining (garder le service après reconnexion) du panneau est activé.

SetJob

Donne un métier à un joueur, ou change le grade d’un métier qu’il a déjà.

Côté : Serveur · Attend : non · Lib : aucune

Signature
SetJob(src: number, job: string, grade: number): boolean
Lua
local ok = exports['ai-core']:SetJob(source, 'mechanic', 0)

Paramètres

Prop

Type

Retour

boolean : true quand le personnage a maintenant job au grade grade. false quand le métier n’existe pas, que le grade n’existe pas (pas un nombre entier, sous 0 ou au-delà du dernier grade), que le personnage a déjà autant de métiers que Most jobs per character l’autorise, ou que le joueur n’a pas de personnage chargé.

Quand le réglage Several jobs per character (plusieurs métiers par personnage) du panneau est désactivé, un nouveau métier remplace l’autre métier du personnage.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// Un pôle emploi : n’importe qui peut prendre un métier que liste le panneau, au grade 0.
onClientCallback(
  "myscript:takeJob",
  { args: ([job]) => { const name = readText(job, 32); return name ? [name] : null; } },
  (source, job) => {
    if (!core.GetJobDefinition(job)?.listed) return fail("JOB_NOT_LISTED");
    return core.SetJob(source, job, 0) ? { ok: true } : fail("JOB_LIMIT");
  },
);

RemoveJob

Retire un métier à un joueur. Un joueur en service pour ce métier quitte d’abord son service.

Côté : Serveur · Attend : non · Lib : aucune

Signature
RemoveJob(src: number, job: string): boolean
Lua
local ok = exports['ai-core']:RemoveJob(source, 'mechanic')

Paramètres

Prop

Type

Retour

boolean : true quand le métier a été retiré. false quand le personnage ne l’a pas ou que le joueur n’a pas de personnage chargé.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback(
  "myscript:quitJob",
  { args: ([job]) => { const name = readText(job, 32); return name ? [name] : null; } },
  (source, job) => (core.RemoveJob(source, job) ? { ok: true } : fail("NOT_MEMBER")),
);

GetOnDutyCount

Combien de joueurs sont en service pour un métier en ce moment. Utilisez-le pour des règles du type « 2 policiers en ligne requis ».

Côté : Serveur · Attend : non · Lib : aucune (online.countOnDuty(jobs) compte plusieurs métiers depuis le miroir de la lib)

Signature
GetOnDutyCount(job: string): number
Lua
local officers = exports['ai-core']:GetOnDutyCount('police')

Paramètres

Prop

Type

Retour

number : les joueurs en service pour job. 0 pour personne ou un métier inconnu. Le même nombre se trouve dans la clé GlobalState ai:duty:<job> pour les scripts client.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");
const POLICE_NEEDED = 2;

onClientCallback("myscript:startRobbery", { lock: true }, (source) => {
  if (core.GetOnDutyCount("police") < POLICE_NEEDED) return fail("NOT_ENOUGH_POLICE");
  // ... lancer le braquage
  return { ok: true };
});

IsPrimeTime

Indique si c’est l’heure de pointe pour un métier maintenant. Les heures de pointe viennent de la source que choisit le panneau : un script qui garde ses propres heures (tgiann-policealert) tant qu’il tourne, sinon les propres heures d’ai-core (la plage propre au métier ou celle par défaut). Utilisez-le pour des règles qui changent avec les heures chargées, comme un braquage qui rapporte plus.

Côté : Serveur · Attend : non · Lib : isPrimeTime(job?)

Signature
IsPrimeTime(job?: string): boolean
Lua
local prime = exports['ai-core']:IsPrimeTime('police')

Paramètres

Prop

Type

Retour

boolean : true pendant l’heure de pointe. Les heures sont l’heure locale du serveur ; une plage dont le début est plus tard que la fin passe minuit, et un même début et une même fin signifient toute la journée. Quand le panneau choisit un script comme source et que ce script est arrêté, chaque heure compte comme heure de pointe. Cela fonctionne que la réduction de paie en heure de pointe soit activée ou non.

Exemple

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

/** A store robbery pays 50% more outside police prime time. */
export function robberyReward(base: number): number {
  return core.IsPrimeTime("police") ? base : Math.round(base * 1.5);
}

GetJobDefinitions

Chaque définition de métier du panneau, en une seule copie. Utilisez-le pour des lectures rares comme construire une liste une fois ; pour un seul métier, utilisez GetJobDefinition.

Côté : Serveur · Attend : non · Lib : aucune

Signature
GetJobDefinitions(): Record<string, JobDefinition>
Lua
local jobs = exports['ai-core']:GetJobDefinitions() -- table indexée par nom de métier

Paramètres

Aucun.

Retour

Record<string, JobDefinition> : chaque métier indexé par nom. Chacun a label, type, defaultDuty, listed (affiché dans les pôles emploi) et grades (chacun avec label, salary et boss). Voir JobDefinition et GradeDefinition.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

// Le pôle emploi liste chaque métier marqué "listed" dans le panneau.
onClientCallback("myscript:jobCenter", () => ({
  ok: true,
  jobs: Object.entries(core.GetJobDefinitions())
    .filter(([, def]) => def.listed)
    .map(([name, def]) => ({ name, label: def.label, salary: def.grades[0]?.salary ?? 0 })),
}));

En Lua, def.grades[1] est le grade 0 : les listes Lua commencent à 1, les grades commencent à 0.

GetJobDefinition

La définition d’un métier : libellé, type, service par défaut, si les pôles emploi le listent, et ses grades.

Côté : Serveur · Attend : non · Lib : definitions.job(name) (lit chaque métier une fois et l’oublie quand le panneau le modifie)

Signature
GetJobDefinition(job: string): JobDefinition | null
Lua
local def = exports['ai-core']:GetJobDefinition('police') -- table ou nil

Paramètres

Prop

Type

Retour

JobDefinition | null : le métier (JobDefinition). null pour un métier inconnu ou une valeur qui n’est pas un texte.

Exemple

import { onClientCallback, online, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

// Seul un grade de patron peut ouvrir le menu de patron.
onClientCallback("myscript:bossMenu", (source) => {
  const job = online.dutyJob(source);
  const grade = job ? online.jobGrade(source, job) : null;
  if (!job || grade === null) return fail("NOT_ON_DUTY");
  if (!core.GetJobDefinition(job)?.grades[grade]?.boss) return fail("NOT_BOSS");
  return { ok: true };
});

GetGangs

Chaque appartenance à un gang du personnage d’un joueur.

Côté : Serveur · Attend : non · Lib : online.gangs(source) lit la même chose depuis le miroir de la lib

Signature
GetGangs(src: number): GangMembership[] | null
Lua
local gangs = exports['ai-core']:GetGangs(source) -- liste de { gang, grade } ou nil

Paramètres

Prop

Type

Retour

GangMembership[] | null : un { gang, grade } par gang (GangMembership). Une liste vide sans gang. null quand le joueur n’a pas de personnage chargé.

Exemple

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

/** Whether a player belongs to any gang (active or not). */
export function inAnyGang(source: number): boolean {
  return (core.GetGangs(source)?.length ?? 0) > 0;
}

GetActiveGang

Le gang que le joueur a actif en ce moment. Les territoires de gang, les coffres de gang et les chats de gang doivent utiliser le gang actif.

Côté : Serveur · Attend : non · Lib : aucune

Signature
GetActiveGang(src: number): string | null
Lua
local gang = exports['ai-core']:GetActiveGang(source) -- nom du gang ou nil

Paramètres

Prop

Type

Retour

string | null : le nom du gang. null quand aucun gang n’est actif ou que le joueur n’a pas de personnage chargé.

Exemple

import { onClientCallback, inventory, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:gangStash", (source) => {
  const gang = core.GetActiveGang(source);
  if (!gang) return fail("NO_GANG");
  return inventory.openInventory(source, `gang_${gang}`) ? { ok: true } : fail("STASH_FAILED");
});

SetGang

Ajoute un joueur à un gang, ou change son grade dans un gang dont il fait partie. Un personnage sans gang actif reçoit le nouveau gang comme gang actif.

Côté : Serveur · Attend : non · Lib : aucune

Signature
SetGang(src: number, gang: string, grade: number): boolean
Lua
local ok = exports['ai-core']:SetGang(source, 'ballas', 0)

Paramètres

Prop

Type

Retour

boolean : true quand le personnage fait maintenant partie de gang au grade grade. false quand le gang ou le grade n’existe pas, que le personnage fait déjà partie d’autant de gangs que Most gangs per character l’autorise, ou que le joueur n’a pas de personnage chargé. Quand le réglage Several gangs per character (plusieurs gangs par personnage) du panneau est désactivé, le nouveau gang remplace l’ancien.

Exemple

import { addCommand, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

addCommand("setgang", {
  help: "Adds a player to a gang",
  params: [{ name: "id", type: "playerId" }, { name: "gang", type: "string" }, { name: "grade", type: "number" }],
  restricted: true,
}, (_source, args) => {
  console.log(core.SetGang(args.id, args.gang, args.grade) ? "done" : "refused");
});

RemoveGang

Retire un joueur d’un gang. Quand c’était le gang actif, le gang restant suivant devient actif (ou aucun).

Côté : Serveur · Attend : non · Lib : aucune

Signature
RemoveGang(src: number, gang: string): boolean
Lua
local ok = exports['ai-core']:RemoveGang(source, 'ballas')

Paramètres

Prop

Type

Retour

boolean : true quand l’appartenance a été retirée. false quand le personnage n’est pas dans ce gang ou que le joueur n’a pas de personnage chargé.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback("myscript:leaveGang", (source) => {
  const gang = core.GetActiveGang(source);
  return gang && core.RemoveGang(source, gang) ? { ok: true } : fail("NO_GANG");
});

SetActiveGang

Choisit lequel des gangs du joueur est actif, ou aucun.

Côté : Serveur · Attend : non · Lib : aucune

Signature
SetActiveGang(src: number, gang: string | null): boolean
Lua
local ok = exports['ai-core']:SetActiveGang(source, 'vagos') -- nil = aucun gang actif

Paramètres

Prop

Type

Retour

boolean : true quand gang est maintenant actif (aussi quand il l’était déjà). false quand le personnage n’est pas dans ce gang ou que le joueur n’a pas de personnage chargé. Le gang actif est enregistré.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";

const core = resourceExport("ai-core");

onClientCallback(
  "myscript:pickGang",
  { args: ([gang]) => { const name = readText(gang, 32); return name ? [name] : null; } },
  (source, gang) => (core.SetActiveGang(source, gang) ? { ok: true } : fail("NOT_MEMBER")),
);

GetGangDefinitions

Chaque définition de gang du panneau, en une seule copie.

Côté : Serveur · Attend : non · Lib : aucune

Signature
GetGangDefinitions(): Record<string, GangDefinition>
Lua
local gangs = exports['ai-core']:GetGangDefinitions() -- table indexée par nom de gang

Paramètres

Aucun.

Retour

Record<string, GangDefinition> : chaque gang indexé par nom, chacun avec label et grades. Voir GangDefinition.

Exemple

import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

onClientCallback("myscript:gangList", () => ({
  ok: true,
  gangs: Object.entries(core.GetGangDefinitions()).map(([name, def]) => ({ name, label: def.label })),
}));

GetGangDefinition

La définition d’un gang : son libellé et ses grades.

Côté : Serveur · Attend : non · Lib : definitions.gang(name)

Signature
GetGangDefinition(gang: string): GangDefinition | null
Lua
local def = exports['ai-core']:GetGangDefinition('ballas') -- table ou nil

Paramètres

Prop

Type

Retour

GangDefinition | null : le gang (GangDefinition). null pour un gang inconnu ou une valeur qui n’est pas un texte.

Exemple

import { resourceExport } from "@aicore-fivem/lib/server";

const core = resourceExport("ai-core");

/** "Ballas" for "ballas", the name itself for an unknown gang. */
export function gangLabel(gang: string): string {
  return core.GetGangDefinition(gang)?.label ?? gang;
}

Sur cette page