Jobs und Gangs
Jobs, Gangs, Ränge und Dienst eines Charakters lesen und ändern, Spieler im Dienst zählen, Prime Time, Job- und Gang-Definitionen lesen.
Ein Charakter kann mehrere Jobs und mehrere Gangs haben (bis zu den Panel-Werten Most jobs per character und Most gangs per character). Höchstens ein Job ist gleichzeitig im Dienst, und nur dieser Job zahlt ein Gehalt. Höchstens eine Gang ist aktiv. Jobs und Gangs mit ihren Rängen werden im Admin-Panel definiert (Bereiche Jobs und Gangs).
Ein Rang ist eine Position in der Rangliste des Jobs, gezählt ab 0: Rang 0 ist die erste Zeile im Panel, Rang 1 die zweite und so weiter.
Jede Änderung löst ein Server-Event aus (ai-core:jobsChanged, ai-core:dutyChanged, ai-core:gangsChanged, ai-core:activeGangChanged) und erreicht das eigene Spiel des Spielers. Ressourcen, die die Jobs vieler Spieler brauchen, folgen diesen Events über den online-Spiegel der Lib, statt die Exports unten für jeden Spieler aufzurufen. Siehe Events und Zustand.
GetJobs
Jede Job-Mitgliedschaft des Charakters eines Spielers.
Seite: Server · Wartet: nein · Lib: online.jobs(source) liest dasselbe aus dem Spiegel der Lib
GetJobs(src: number): JobMembership[] | nulllocal jobs = exports['ai-core']:GetJobs(source) -- Liste von { job, grade } oder nilParameter
Prop
Type
Rückgabe
JobMembership[] | null: ein { job, grade } pro Job (JobMembership). Eine leere Liste, wenn der Charakter keinen Job hat (der Arbeitslosen-Job des Panels wird nie gespeichert). null, wenn der Spieler keinen geladenen Charakter hat.
Beispiel
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Ein Jobcenter-Bildschirm listet die Jobs des Spielers mit ihren Labels.
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
Der eine Job, den andere Skripte als „den“ Job des Spielers behandeln sollen: der Job im Dienst, sonst der letzte Job, für den der Spieler im Dienst war, sonst der erste Job, sonst der Arbeitslosen-Job des Panels. ESX- und QB-Skripte sehen diesen Job über die Brücke.
Seite: Server · Wartet: nein · Lib: keine
GetCurrentJob(src: number): JobMembership | nulllocal job = exports['ai-core']:GetCurrentJob(source) -- { job, grade } oder nilParameter
Prop
Type
Rückgabe
JobMembership | null: { job, grade }. Für einen Charakter ohne Job ist es der Arbeitslosen-Job (Panel-Einstellung, standardmäßig unemployed) mit Rang 0. null nur, wenn der Spieler keinen geladenen Charakter hat.
Beispiel
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
Der Job, für den der Spieler gerade im Dienst ist. Nutze es für jede Prüfung der Art „nur Polizei im Dienst darf das“.
Seite: Server · Wartet: nein · Lib: online.dutyJob(source) liest dasselbe aus dem Spiegel der Lib
GetDutyJob(src: number): string | nulllocal job = exports['ai-core']:GetDutyJob(source) -- Jobname oder nilParameter
Prop
Type
Rückgabe
string | null: der Jobname. null, wenn der Spieler nicht im Dienst ist oder keinen geladenen Charakter hat.
Beispiel
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
Setzt einen Spieler für einen seiner Jobs in den Dienst (und für jeden anderen außer Dienst) oder außer Dienst.
Seite: Server · Wartet: nein · Lib: keine
SetDuty(src: number, job: string | null): booleanlocal ok = exports['ai-core']:SetDuty(source, 'police') -- nil = außer DienstParameter
Prop
Type
Rückgabe
boolean: true, wenn der Spieler jetzt für job im Dienst ist (oder bei null außer Dienst), auch wenn sich nichts ändern musste. false, wenn der Spieler job nicht hat oder keinen geladenen Charakter hat.
Beispiel
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 };
// Ein Dienstschalter im Umkleideraum der Wache.
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");
});Der Dienst wird nicht gespeichert: Ein Spieler, der beitritt, ist außer Dienst, es sei denn, die Panel-Einstellung Keep duty after rejoining (Dienst nach erneutem Beitritt behalten) ist aktiv.
SetJob
Gibt einem Spieler einen Job oder ändert den Rang eines Jobs, den er bereits hat.
Seite: Server · Wartet: nein · Lib: keine
SetJob(src: number, job: string, grade: number): booleanlocal ok = exports['ai-core']:SetJob(source, 'mechanic', 0)Parameter
Prop
Type
Rückgabe
boolean: true, wenn der Charakter jetzt job mit grade hat. false, wenn der Job nicht existiert, der Rang nicht existiert (keine ganze Zahl, unter 0 oder nach dem letzten Rang), der Charakter bereits so viele Jobs hat, wie Most jobs per character erlaubt, oder der Spieler keinen geladenen Charakter hat.
Wenn die Panel-Einstellung Several jobs per character (mehrere Jobs pro Charakter) aus ist, ersetzt ein neuer Job den anderen Job des Charakters.
Beispiel
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Ein Jobcenter: Jeder darf einen Job, den das Panel listet, mit Rang 0 annehmen.
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
Nimmt einem Spieler einen Job weg. Ein Spieler, der für diesen Job im Dienst ist, geht zuerst außer Dienst.
Seite: Server · Wartet: nein · Lib: keine
RemoveJob(src: number, job: string): booleanlocal ok = exports['ai-core']:RemoveJob(source, 'mechanic')Parameter
Prop
Type
Rückgabe
boolean: true, wenn der Job entfernt wurde. false, wenn der Charakter ihn nicht hat oder der Spieler keinen geladenen Charakter hat.
Beispiel
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
Wie viele Spieler gerade für einen Job im Dienst sind. Nutze es für Regeln wie „braucht 2 Polizisten online“.
Seite: Server · Wartet: nein · Lib: keine (online.countOnDuty(jobs) zählt mehrere Jobs aus dem Spiegel der Lib)
GetOnDutyCount(job: string): numberlocal officers = exports['ai-core']:GetOnDutyCount('police')Parameter
Prop
Type
Rückgabe
number: Spieler im Dienst für job. 0 für niemanden oder einen unbekannten Job. Dieselbe Zahl steht für Client-Skripte im GlobalState ai:duty:<job>.
Beispiel
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");
// ... den Überfall starten
return { ok: true };
});IsPrimeTime
Ob gerade Prime Time für einen Job ist. Die Prime-Time-Stunden kommen aus der Quelle, die das Panel wählt: ein Skript, das eigene Stunden führt (tgiann-policealert), solange es läuft, sonst die eigenen Stunden von ai-core (das eigene Zeitfenster des Jobs oder das Standardfenster). Nutze es für Regeln, die sich mit den Stoßzeiten ändern, etwa einen Überfall, der mehr bringt.
Seite: Server · Wartet: nein · Lib: isPrimeTime(job?)
IsPrimeTime(job?: string): booleanlocal prime = exports['ai-core']:IsPrimeTime('police')Parameter
Prop
Type
Rückgabe
boolean: true während der Prime Time. Die Stunden sind die lokale Zeit des Servers; ein Fenster, dessen Start später als sein Ende liegt, läuft über Mitternacht, und gleicher Start und gleiches Ende bedeuten den ganzen Tag. Wenn das Panel ein Skript als Quelle wählt und dieses Skript gestoppt ist, zählt jede Stunde als Prime Time. Es funktioniert unabhängig davon, ob die Prime-Time-Kürzung des Gehalts aktiv ist.
Beispiel
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Ein Ladenüberfall bringt außerhalb der Polizei-Prime-Time 50 % mehr. */
export function robberyReward(base: number): number {
return core.IsPrimeTime("police") ? base : Math.round(base * 1.5);
}GetJobDefinitions
Jede Job-Definition aus dem Panel, als eine Kopie. Nutze es für seltene Lesevorgänge, etwa um eine Liste einmal aufzubauen; für einen einzelnen Job nutze GetJobDefinition.
Seite: Server · Wartet: nein · Lib: keine
GetJobDefinitions(): Record<string, JobDefinition>local jobs = exports['ai-core']:GetJobDefinitions() -- Tabelle mit Jobnamen als SchlüsselParameter
Keine.
Rückgabe
Record<string, JobDefinition>: jeder Job nach Namen. Jeder hat label, type, defaultDuty, listed (in Jobcentern angezeigt) und grades (jeder mit label, salary und boss). Siehe JobDefinition und GradeDefinition.
Beispiel
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// Das Jobcenter listet jeden Job, der im Panel als „listed“ markiert ist.
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 })),
}));In Lua ist def.grades[1] Rang 0: Lua-Listen beginnen bei 1, Ränge bei 0.
GetJobDefinition
Die Definition eines Jobs: Label, Typ, Standarddienst, ob Jobcenter ihn listen, und seine Ränge.
Seite: Server · Wartet: nein · Lib: definitions.job(name) (liest jeden Job einmal und vergisst ihn, wenn das Panel ihn ändert)
GetJobDefinition(job: string): JobDefinition | nulllocal def = exports['ai-core']:GetJobDefinition('police') -- Tabelle oder nilParameter
Prop
Type
Rückgabe
JobDefinition | null: der Job (JobDefinition). null für einen unbekannten Job oder einen Wert, der kein Text ist.
Beispiel
import { onClientCallback, online, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Nur ein Chef-Rang darf das Chefmenü öffnen.
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
Jede Gang-Mitgliedschaft des Charakters eines Spielers.
Seite: Server · Wartet: nein · Lib: online.gangs(source) liest dasselbe aus dem Spiegel der Lib
GetGangs(src: number): GangMembership[] | nulllocal gangs = exports['ai-core']:GetGangs(source) -- Liste von { gang, grade } oder nilParameter
Prop
Type
Rückgabe
GangMembership[] | null: ein { gang, grade } pro Gang (GangMembership). Eine leere Liste ohne Gangs. null, wenn der Spieler keinen geladenen Charakter hat.
Beispiel
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** Ob ein Spieler zu irgendeiner Gang gehört (aktiv oder nicht). */
export function inAnyGang(source: number): boolean {
return (core.GetGangs(source)?.length ?? 0) > 0;
}GetActiveGang
Die Gang, die der Spieler gerade aktiv hat. Gang-Gebiete, Gang-Lager und Gang-Chats sollten die aktive Gang nutzen.
Seite: Server · Wartet: nein · Lib: keine
GetActiveGang(src: number): string | nulllocal gang = exports['ai-core']:GetActiveGang(source) -- Gangname oder nilParameter
Prop
Type
Rückgabe
string | null: der Gangname. null, wenn keine Gang aktiv ist oder der Spieler keinen geladenen Charakter hat.
Beispiel
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
Fügt einen Spieler einer Gang hinzu oder ändert seinen Rang in einer Gang, zu der er gehört. Ein Charakter ohne aktive Gang bekommt die neue Gang als aktive.
Seite: Server · Wartet: nein · Lib: keine
SetGang(src: number, gang: string, grade: number): booleanlocal ok = exports['ai-core']:SetGang(source, 'ballas', 0)Parameter
Prop
Type
Rückgabe
boolean: true, wenn der Charakter jetzt mit grade zu gang gehört. false, wenn die Gang oder der Rang nicht existiert, der Charakter bereits zu so vielen Gangs gehört, wie Most gangs per character erlaubt, oder der Spieler keinen geladenen Charakter hat. Wenn die Panel-Einstellung Several gangs per character (mehrere Gangs pro Charakter) aus ist, ersetzt die neue Gang die alte.
Beispiel
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
Entfernt einen Spieler aus einer Gang. War es die aktive Gang, wird die nächste verbleibende Gang aktiv (oder keine).
Seite: Server · Wartet: nein · Lib: keine
RemoveGang(src: number, gang: string): booleanlocal ok = exports['ai-core']:RemoveGang(source, 'ballas')Parameter
Prop
Type
Rückgabe
boolean: true, wenn die Mitgliedschaft entfernt wurde. false, wenn der Charakter nicht in dieser Gang ist oder der Spieler keinen geladenen Charakter hat.
Beispiel
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
Wählt, welche der Gangs des Spielers aktiv ist, oder keine.
Seite: Server · Wartet: nein · Lib: keine
SetActiveGang(src: number, gang: string | null): booleanlocal ok = exports['ai-core']:SetActiveGang(source, 'vagos') -- nil = keine aktive GangParameter
Prop
Type
Rückgabe
boolean: true, wenn gang jetzt aktiv ist (auch wenn sie es schon war). false, wenn der Charakter nicht in dieser Gang ist oder der Spieler keinen geladenen Charakter hat. Die aktive Gang wird gespeichert.
Beispiel
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
Jede Gang-Definition aus dem Panel, als eine Kopie.
Seite: Server · Wartet: nein · Lib: keine
GetGangDefinitions(): Record<string, GangDefinition>local gangs = exports['ai-core']:GetGangDefinitions() -- Tabelle mit Gangnamen als SchlüsselParameter
Keine.
Rückgabe
Record<string, GangDefinition>: jede Gang nach Namen, jede mit label und grades. Siehe GangDefinition.
Beispiel
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
Die Definition einer Gang: ihr Label und ihre Ränge.
Seite: Server · Wartet: nein · Lib: definitions.gang(name)
GetGangDefinition(gang: string): GangDefinition | nulllocal def = exports['ai-core']:GetGangDefinition('ballas') -- Tabelle oder nilParameter
Prop
Type
Rückgabe
GangDefinition | null: die Gang (GangDefinition). null für eine unbekannte Gang oder einen Wert, der kein Text ist.
Beispiel
import { resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
/** „Ballas“ für „ballas“, der Name selbst für eine unbekannte Gang. */
export function gangLabel(gang: string): string {
return core.GetGangDefinition(gang)?.label ?? gang;
}Geld und Konten
Die Kontostände eines Spielers sowie Job- und Gang-Konten lesen und ändern, Geld in einer Transaktion zwischen zwei Konten bewegen, die Kontotypen lesen.
Metadaten und Einstellungen
Den Metadaten-Beutel eines Charakters lesen und schreiben, das Branding des Servers und die Liste veralteter Skripte lesen.