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
GetJobs(src: number): JobMembership[] | nulllocal jobs = exports['ai-core']:GetJobs(source) -- liste de { job, grade } ou nilParamè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
GetCurrentJob(src: number): JobMembership | nulllocal job = exports['ai-core']:GetCurrentJob(source) -- { job, grade } ou nilParamè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
GetDutyJob(src: number): string | nulllocal job = exports['ai-core']:GetDutyJob(source) -- nom du métier ou nilParamè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
SetDuty(src: number, job: string | null): booleanlocal ok = exports['ai-core']:SetDuty(source, 'police') -- nil = hors serviceParamè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
SetJob(src: number, job: string, grade: number): booleanlocal 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
RemoveJob(src: number, job: string): booleanlocal 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)
GetOnDutyCount(job: string): numberlocal 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?)
IsPrimeTime(job?: string): booleanlocal 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
GetJobDefinitions(): Record<string, JobDefinition>local jobs = exports['ai-core']:GetJobDefinitions() -- table indexée par nom de métierParamè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)
GetJobDefinition(job: string): JobDefinition | nulllocal def = exports['ai-core']:GetJobDefinition('police') -- table ou nilParamè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
GetGangs(src: number): GangMembership[] | nulllocal gangs = exports['ai-core']:GetGangs(source) -- liste de { gang, grade } ou nilParamè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
GetActiveGang(src: number): string | nulllocal gang = exports['ai-core']:GetActiveGang(source) -- nom du gang ou nilParamè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
SetGang(src: number, gang: string, grade: number): booleanlocal 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
RemoveGang(src: number, gang: string): booleanlocal 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
SetActiveGang(src: number, gang: string | null): booleanlocal ok = exports['ai-core']:SetActiveGang(source, 'vagos') -- nil = aucun gang actifParamè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
GetGangDefinitions(): Record<string, GangDefinition>local gangs = exports['ai-core']:GetGangDefinitions() -- table indexée par nom de gangParamè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)
GetGangDefinition(gang: string): GangDefinition | nulllocal def = exports['ai-core']:GetGangDefinition('ballas') -- table ou nilParamè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;
}Argent et comptes
Lire et modifier les soldes d’un joueur, les comptes de métier et de gang, déplacer de l’argent entre deux comptes en une seule transaction, lire les types de comptes.
Métadonnées et réglages
Lire et écrire le sac de métadonnées d’un personnage, lire l’identité visuelle du serveur et la liste des scripts obsolètes.