Empregos e gangues
Leia e altere os empregos, gangues, cargos e serviço de um personagem, conte jogadores em serviço, horário nobre, leia definições de empregos e gangues.
Um personagem pode ter vários empregos e várias gangues (até Most jobs per character e Most gangs per character do painel). No máximo um emprego fica em serviço de cada vez, e só esse emprego paga salário. No máximo uma gangue fica ativa. Empregos e gangues, com seus cargos, são definidos no painel de administração (seções Jobs e Gangs).
Um cargo é uma posição na lista de cargos do emprego, contada a partir de 0: o cargo 0 é a primeira linha no painel, o cargo 1 a segunda, e assim por diante.
Cada mudança dispara um evento de servidor (ai-core:jobsChanged, ai-core:dutyChanged, ai-core:gangsChanged, ai-core:activeGangChanged) e chega ao próprio jogo do jogador. Recursos que precisam dos empregos de muitos jogadores seguem esses eventos pelo espelho online da lib em vez de chamar os exports abaixo para cada jogador. Veja Eventos e estado.
GetJobs
Cada vínculo de emprego do personagem de um jogador.
Lado: Servidor · Espera: não · Lib: online.jobs(source) lê o mesmo do espelho da lib
GetJobs(src: number): JobMembership[] | nulllocal jobs = exports['ai-core']:GetJobs(source) -- lista de { job, grade } ou nilParâmetros
Prop
Type
Retorno
JobMembership[] | null: um { job, grade } por emprego (JobMembership). Uma lista vazia quando o personagem não tem emprego (o emprego de desempregado do painel nunca é gravado). null quando o jogador não tem personagem carregado.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// A tela de uma agência de empregos lista os empregos do jogador com seus rótulos.
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
O único emprego que os outros scripts devem tratar como "o" emprego do jogador: o emprego em serviço, senão o último emprego em que o jogador esteve em serviço, senão o primeiro emprego, senão o emprego de desempregado do painel. Os scripts de ESX e QB veem este emprego pela ponte.
Lado: Servidor · Espera: não · Lib: nenhuma
GetCurrentJob(src: number): JobMembership | nulllocal job = exports['ai-core']:GetCurrentJob(source) -- { job, grade } ou nilParâmetros
Prop
Type
Retorno
JobMembership | null: { job, grade }. Para um personagem sem nenhum emprego é o emprego de desempregado (configuração do painel, unemployed por padrão) com cargo 0. null só quando o jogador não tem personagem carregado.
Exemplo
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
O emprego em que o jogador está em serviço agora. Use para toda verificação do tipo "só a polícia em serviço pode fazer isto".
Lado: Servidor · Espera: não · Lib: online.dutyJob(source) lê o mesmo do espelho da lib
GetDutyJob(src: number): string | nulllocal job = exports['ai-core']:GetDutyJob(source) -- nome do emprego ou nilParâmetros
Prop
Type
Retorno
string | null: o nome do emprego. null quando o jogador está fora de serviço ou não tem personagem carregado.
Exemplo
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
Coloca um jogador em serviço num dos empregos dele (e fora de serviço em qualquer outro), ou fora de serviço.
Lado: Servidor · Espera: não · Lib: nenhuma
SetDuty(src: number, job: string | null): booleanlocal ok = exports['ai-core']:SetDuty(source, 'police') -- nil = fora de serviçoParâmetros
Prop
Type
Retorno
boolean: true quando o jogador agora está em serviço em job (ou fora de serviço para null), também quando nada precisou mudar. false quando o jogador não tem job ou não tem personagem carregado.
Exemplo
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 };
// Um interruptor de serviço no vestiário da delegacia.
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");
});O serviço não é salvo: um jogador que entra fica fora de serviço, a menos que a configuração Keep duty after rejoining do painel esteja ligada.
SetJob
Dá um emprego a um jogador, ou muda o cargo de um emprego que ele já tem.
Lado: Servidor · Espera: não · Lib: nenhuma
SetJob(src: number, job: string, grade: number): booleanlocal ok = exports['ai-core']:SetJob(source, 'mechanic', 0)Parâmetros
Prop
Type
Retorno
boolean: true quando o personagem agora tem job no cargo grade. false quando o emprego não existe, o cargo não existe (não é um número inteiro, está abaixo de 0 ou passa do último cargo), o personagem já tem tantos empregos quanto Most jobs per character permite ou o jogador não tem personagem carregado.
Quando a configuração Several jobs per character do painel está desligada, um novo emprego substitui o outro emprego do personagem.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
import { fail, readText } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Uma agência de empregos: qualquer um pode pegar um emprego que o painel lista, no cargo 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
Tira um emprego de um jogador. Um jogador em serviço nesse emprego sai de serviço antes.
Lado: Servidor · Espera: não · Lib: nenhuma
RemoveJob(src: number, job: string): booleanlocal ok = exports['ai-core']:RemoveJob(source, 'mechanic')Parâmetros
Prop
Type
Retorno
boolean: true quando o emprego foi removido. false quando o personagem não o tem ou o jogador não tem personagem carregado.
Exemplo
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
Quantos jogadores estão em serviço num emprego agora. Use para regras do tipo "precisa de 2 policiais online".
Lado: Servidor · Espera: não · Lib: nenhuma (online.countOnDuty(jobs) conta vários empregos a partir do espelho da lib)
GetOnDutyCount(job: string): numberlocal officers = exports['ai-core']:GetOnDutyCount('police')Parâmetros
Prop
Type
Retorno
number: jogadores em serviço em job. 0 para ninguém ou um emprego desconhecido. O mesmo número fica no GlobalState ai:duty:<job> para scripts de cliente.
Exemplo
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");
// ... inicia o assalto
return { ok: true };
});IsPrimeTime
Se agora é horário nobre para um emprego. As horas do horário nobre vêm da fonte que o painel escolhe: um script que mantém as próprias horas (tgiann-policealert) enquanto ele roda, senão as horas próprias do ai-core (a janela do próprio emprego ou a padrão). Use para regras que mudam com as horas de movimento, como um assalto que paga mais.
Lado: Servidor · Espera: não · Lib: isPrimeTime(job?)
IsPrimeTime(job?: string): booleanlocal prime = exports['ai-core']:IsPrimeTime('police')Parâmetros
Prop
Type
Retorno
boolean: true durante o horário nobre. As horas são o horário local do servidor; uma janela cujo início é depois do fim passa da meia-noite, e o mesmo início e fim significa o dia inteiro. Quando o painel escolhe um script como fonte e esse script está parado, toda hora conta como horário nobre. Funciona esteja ou não ligado o corte do salário no horário nobre.
Exemplo
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
Cada definição de emprego do painel, como uma cópia. Use para leituras raras, como montar uma lista uma vez; para um emprego use GetJobDefinition.
Lado: Servidor · Espera: não · Lib: nenhuma
GetJobDefinitions(): Record<string, JobDefinition>local jobs = exports['ai-core']:GetJobDefinitions() -- table indexada pelo nome do empregoParâmetros
Nenhum.
Retorno
Record<string, JobDefinition>: cada emprego indexado pelo nome. Cada um tem label, type, defaultDuty, listed (mostrado nas agências de empregos) e grades (cada um com label, salary e boss). Veja JobDefinition e GradeDefinition.
Exemplo
import { onClientCallback, resourceExport } from "@aicore-fivem/lib/server";
const core = resourceExport("ai-core");
// A agência de empregos lista cada emprego marcado como "listed" no painel.
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 })),
}));Em Lua, def.grades[1] é o cargo 0: as listas de Lua começam em 1, os cargos começam em 0.
GetJobDefinition
A definição de um emprego: rótulo, tipo, serviço padrão, se as agências de empregos o listam, e os cargos dele.
Lado: Servidor · Espera: não · Lib: definitions.job(name) (lê cada emprego uma vez e o esquece quando o painel o muda)
GetJobDefinition(job: string): JobDefinition | nulllocal def = exports['ai-core']:GetJobDefinition('police') -- table ou nilParâmetros
Prop
Type
Retorno
JobDefinition | null: o emprego (JobDefinition). null para um emprego desconhecido ou um valor que não é texto.
Exemplo
import { onClientCallback, online, resourceExport } from "@aicore-fivem/lib/server";
import { fail } from "@aicore-fivem/lib/shared";
const core = resourceExport("ai-core");
// Só um cargo de chefe pode abrir o menu de chefe.
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
Cada vínculo de gangue do personagem de um jogador.
Lado: Servidor · Espera: não · Lib: online.gangs(source) lê o mesmo do espelho da lib
GetGangs(src: number): GangMembership[] | nulllocal gangs = exports['ai-core']:GetGangs(source) -- lista de { gang, grade } ou nilParâmetros
Prop
Type
Retorno
GangMembership[] | null: um { gang, grade } por gangue (GangMembership). Uma lista vazia sem gangues. null quando o jogador não tem personagem carregado.
Exemplo
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
A gangue que o jogador tem ativa agora. Território de gangue, baús de gangue e chats de gangue devem usar a gangue ativa.
Lado: Servidor · Espera: não · Lib: nenhuma
GetActiveGang(src: number): string | nulllocal gang = exports['ai-core']:GetActiveGang(source) -- nome da gangue ou nilParâmetros
Prop
Type
Retorno
string | null: o nome da gangue. null quando nenhuma gangue está ativa ou o jogador não tem personagem carregado.
Exemplo
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
Adiciona um jogador a uma gangue, ou muda o cargo dele numa gangue a que pertence. Um personagem sem gangue ativa recebe a nova gangue como ativa.
Lado: Servidor · Espera: não · Lib: nenhuma
SetGang(src: number, gang: string, grade: number): booleanlocal ok = exports['ai-core']:SetGang(source, 'ballas', 0)Parâmetros
Prop
Type
Retorno
boolean: true quando o personagem agora pertence a gang no cargo grade. false quando a gangue ou o cargo não existe, o personagem já pertence a tantas gangues quanto Most gangs per character permite ou o jogador não tem personagem carregado. Quando a configuração Several gangs per character do painel está desligada, a nova gangue substitui a antiga.
Exemplo
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
Remove um jogador de uma gangue. Quando era a gangue ativa, a próxima gangue que sobra fica ativa (ou nenhuma).
Lado: Servidor · Espera: não · Lib: nenhuma
RemoveGang(src: number, gang: string): booleanlocal ok = exports['ai-core']:RemoveGang(source, 'ballas')Parâmetros
Prop
Type
Retorno
boolean: true quando o vínculo foi removido. false quando o personagem não está nessa gangue ou o jogador não tem personagem carregado.
Exemplo
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
Escolhe qual das gangues do jogador fica ativa, ou nenhuma.
Lado: Servidor · Espera: não · Lib: nenhuma
SetActiveGang(src: number, gang: string | null): booleanlocal ok = exports['ai-core']:SetActiveGang(source, 'vagos') -- nil = nenhuma gangue ativaParâmetros
Prop
Type
Retorno
boolean: true quando gang agora está ativa (também quando já estava). false quando o personagem não está nessa gangue ou o jogador não tem personagem carregado. A gangue ativa é salva.
Exemplo
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
Cada definição de gangue do painel, como uma cópia.
Lado: Servidor · Espera: não · Lib: nenhuma
GetGangDefinitions(): Record<string, GangDefinition>local gangs = exports['ai-core']:GetGangDefinitions() -- table indexada pelo nome da gangueParâmetros
Nenhum.
Retorno
Record<string, GangDefinition>: cada gangue indexada pelo nome, cada uma com label e grades. Veja GangDefinition.
Exemplo
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
A definição de uma gangue: o rótulo e os cargos dela.
Lado: Servidor · Espera: não · Lib: definitions.gang(name)
GetGangDefinition(gang: string): GangDefinition | nulllocal def = exports['ai-core']:GetGangDefinition('ballas') -- table ou nilParâmetros
Prop
Type
Retorno
GangDefinition | null: a gangue (GangDefinition). null para uma gangue desconhecida ou um valor que não é texto.
Exemplo
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;
}Dinheiro e contas
Leia e altere os saldos de um jogador e as contas de empregos e gangues, mova dinheiro entre duas contas numa só transação, leia os tipos de conta.
Metadata e configurações
Leia e escreva o saco de metadata de um personagem, leia a identidade visual do servidor e a lista de scripts desatualizados.