AI Core
Referência da APIAI Core: exports de servidor

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.

Todo personagem tem um saldo por tipo de conta. Os tipos vêm da lista Accounts do painel de administração; um servidor novo tem cash, bank, black_money e crypto. Cada emprego e gangue também tem uma conta de cada tipo (o dinheiro da sociedade), que começa vazia.

Como o dinheiro funciona no ai-core:

  • As quantias são números inteiros (dólares, sem centavos). Uma fração, NaN ou um número além da faixa de inteiros seguros do JavaScript é recusado.
  • Uma mudança vale na hora na memória e é gravada no banco de dados em cerca de 50 ms, junto com uma linha no livro-razão (ai_core_transactions). O livro-razão grava o reason que você passa; sem ele, grava o nome do recurso que chamou.
  • Um saldo não pode ficar abaixo de 0, a menos que o tipo de conta tenha Can go below zero ligado no painel.
  • Cada mudança na conta de um jogador dispara o evento de servidor ai-core:moneyChanged (src, account, balance, delta, reason) e chega ao próprio jogo do jogador. Veja Eventos e estado.

GetMoney

O saldo de um jogador numa conta.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
GetMoney(src: number, account: string): number | null
Lua
local balance = exports['ai-core']:GetMoney(source, 'bank') -- number ou nil

Parâmetros

Prop

Type

Retorno

number | null: o saldo. null quando o jogador não tem personagem carregado ou o tipo de conta não existe.

Exemplo

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

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

onClientCallback("myscript:balance", (source) => {
  const bank = core.GetMoney(source, "bank");
  if (bank === null) return fail("NO_CHARACTER");
  return { ok: true, bank };
});

AddMoney

Adiciona dinheiro à conta de um jogador. Use para recompensas, salários que seu script paga ou receita de vendas.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
AddMoney(src: number, account: string, amount: number, reason?: string): boolean
Lua
local ok = exports['ai-core']:AddMoney(source, 'cash', 250, 'fishing_sale')

Parâmetros

Prop

Type

Retorno

boolean: true quando o dinheiro foi adicionado. false quando o jogador não tem personagem carregado, o tipo de conta não existe ou amount não é um número inteiro acima de 0.

Exemplo

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

const core = resourceExport("ai-core");
const BUYER = { x: -1845.2, y: -1197.4, z: 14.3 };

onClientCallback("myscript:sellFish", { guards: [near(BUYER, 3)], lock: true }, (source) => {
  const fish = inventory.getItemCount(source, "fish");
  if (fish < 1) return fail("NO_FISH");
  if (!inventory.removeItem(source, "fish", fish)) return fail("SELL_FAILED");
  core.AddMoney(source, "cash", fish * 25, "fishing_sale");
  return { ok: true };
});

Para mover dinheiro de uma conta para outra (um jogador pagando um emprego, uma transferência bancária), use TransferMoney, não um par RemoveMoney + AddMoney: uma transferência é uma só transação no banco de dados, um par são duas mudanças separadas.

RemoveMoney

Tira dinheiro da conta de um jogador. Use para cobrar por algo.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
RemoveMoney(src: number, account: string, amount: number, reason?: string): boolean
Lua
local paid = exports['ai-core']:RemoveMoney(source, 'bank', 500, 'license_fee')

Parâmetros

Prop

Type

Retorno

boolean: true quando o dinheiro foi tirado. false quando o saldo é baixo demais (e o tipo de conta não permite saldo negativo), o jogador não tem personagem carregado, o tipo de conta não existe ou amount não é um número inteiro acima de 0. Com false nada mudou.

Exemplo

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

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

onClientCallback("myscript:buyLicense", { lock: true }, (source) => {
  if (!inventory.canCarryItem(source, "driver_license")) return fail("NO_SPACE");
  if (!core.RemoveMoney(source, "bank", PRICE, "license_fee")) return fail("NOT_ENOUGH_MONEY");
  inventory.addItem(source, "driver_license");
  return { ok: true };
});

Verifique o que pode falhar antes de tirar o dinheiro (espaço no inventário, estoque), ou devolva o dinheiro com AddMoney quando o próximo passo falhar.

SetMoney

Define o saldo de um jogador para um valor exato. Use para ferramentas de admin; recursos do jogo devem adicionar e remover.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
SetMoney(src: number, account: string, amount: number, reason?: string): boolean
Lua
local ok = exports['ai-core']:SetMoney(source, 'cash', 0, 'admin_reset')

Parâmetros

Prop

Type

Retorno

boolean: true quando o saldo agora é amount (também quando já era). false quando o jogador não tem personagem carregado, o tipo de conta não existe, amount não é um número inteiro ou está abaixo de 0 numa conta que não permite isso.

Exemplo

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

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

addCommand("setcash", {
  help: "Sets a player cash",
  params: [{ name: "id", type: "playerId" }, { name: "amount", type: "number" }],
  restricted: true,
}, (_source, args) => {
  console.log(core.SetMoney(args.id, "cash", args.amount, "admin_set") ? "done" : "refused");
});

GetSharedMoney

O saldo da conta de um emprego ou de uma gangue (dinheiro da sociedade).

Lado: Servidor · Espera: não · Lib: nenhuma (banking.societyBalance pergunta à camada de banco, que pode ler de um script de banco)

Assinatura
GetSharedMoney(ownerType: "job" | "gang", ownerId: string, account: string): number | null
Lua
local balance = exports['ai-core']:GetSharedMoney('job', 'police', 'bank') -- number ou nil

Parâmetros

Prop

Type

Retorno

number | null: o saldo. null quando o emprego, a gangue ou o tipo de conta não existe (ou as contas dele ainda não foram carregadas).

Exemplo

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

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

// Um menu de chefe mostra o dinheiro do emprego; só membros do emprego podem pedir.
onClientCallback("myscript:societyBalance", (source) => {
  const job = online.dutyJob(source);
  if (!job) return fail("NOT_ON_DUTY");
  return { ok: true, balance: core.GetSharedMoney("job", job, "bank") ?? 0 };
});

Quando a configuração Job and gang accounts do painel está em The script's own accounts, as contas bank dos empregos e gangues ficam nesse script: este export então lê o saldo do script. Veja Banco.

AddSharedMoney

Adiciona dinheiro à conta de um emprego ou de uma gangue.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
AddSharedMoney(
  ownerType: "job" | "gang",
  ownerId: string,
  account: string,
  amount: number,
  reason?: string,
): boolean
Lua
local ok = exports['ai-core']:AddSharedMoney('job', 'mechanic', 'bank', 300, 'repair_fee')

Parâmetros

Prop

Type

Retorno

boolean: true quando o dinheiro foi adicionado. false quando o emprego, a gangue ou a conta não existe ou amount não é um número inteiro acima de 0.

Exemplo

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

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

/** A sale made by an NPC customer goes into the restaurant's account. */
export function restaurantSale(job: string, price: number): void {
  if (!core.AddSharedMoney("job", job, "bank", price, "npc_sale"))
    console.log(`job ${job} has no bank account`);
}

Quando um jogador paga o emprego, use TransferMoney da conta do jogador para a do emprego: uma transação, as duas linhas no livro-razão.

RemoveSharedMoney

Tira dinheiro da conta de um emprego ou de uma gangue.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
RemoveSharedMoney(
  ownerType: "job" | "gang",
  ownerId: string,
  account: string,
  amount: number,
  reason?: string,
): boolean
Lua
local ok = exports['ai-core']:RemoveSharedMoney('job', 'police', 'bank', 2000, 'equipment')

Parâmetros

Prop

Type

Retorno

boolean: true quando o dinheiro foi tirado. false quando o saldo é baixo demais (e saldos negativos não são permitidos), o emprego, a gangue ou a conta não existe ou amount não é um número inteiro acima de 0.

Exemplo

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

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

// Um emprego encomenda suprimentos com a própria conta.
onClientCallback("myscript:orderSupplies", { lock: true }, (source) => {
  const job = online.dutyJob(source);
  if (!job) return fail("NOT_ON_DUTY");
  if (!core.RemoveSharedMoney("job", job, "bank", 1500, "supplies")) return fail("SOCIETY_NO_MONEY");
  return { ok: true };
});

TransferMoney

Move dinheiro de uma conta para outra em uma só transação no banco de dados, com as duas linhas no livro-razão. Cada lado pode ser a conta de um jogador carregado ou a conta de um emprego ou gangue. Use para todo pagamento entre duas contas: um jogador pagando um negócio, uma transferência bancária, um depósito na sociedade.

Lado: Servidor · Espera: não · Lib: money.transfer

Assinatura
TransferMoney(from: MoneyRef, to: MoneyRef, amount: number, reason?: string, fee?: number): boolean
Lua
local ok = exports['ai-core']:TransferMoney(
  { source = source, account = 'bank' },
  { owner = 'job', id = 'mechanic', account = 'bank' },
  750, 'repair', 0)

Parâmetros

Prop

Type

MoneyRef é { source, account } para a conta de um jogador carregado, ou { owner, id, account } para a conta de um emprego ou gangue. Veja MoneyRef.

Retorno

boolean: true quando from pagou amount + fee e to recebeu amount. false quando falta uma conta (jogador não carregado, emprego desconhecido, tipo de conta desconhecido), os dois lados são a mesma conta, from não consegue pagar amount + fee, amount não é um número inteiro acima de 0 ou fee não é um número inteiro de 0 ou mais. Com false nada mudou.

Exemplo

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

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

// Um depósito no caixa eletrônico na conta da própria gangue do jogador, com taxa de 2%.
onClientCallback(
  "myscript:gangDeposit",
  { args: ([amount]) => { const n = readInt(amount, 1, 1_000_000); return n === null ? null : [n]; }, lock: true },
  (source, amount) => {
    const gang = core.GetActiveGang(source);
    if (!gang) return fail("NO_GANG");
    const fee = Math.ceil(amount * 0.02);
    const ok = core.TransferMoney(
      { source, account: "bank" },
      { owner: "gang", id: gang, account: "bank" },
      amount, "gang_deposit", fee,
    );
    return ok ? { ok: true } : fail("NOT_ENOUGH_MONEY");
  },
);

Os dois lados disparam a mudança de sempre (o lado de um jogador dispara ai-core:moneyChanged). Dois jogadores podem ser os dois lados: { source: a, account: "bank" } para { source: b, account: "bank" }.

GetAccountTypes

Cada tipo de conta da lista Accounts do painel, com o rótulo, a quantia inicial e se pode ficar negativo. Use para montar um menu de contas ou verificar um nome.

Lado: Servidor · Espera: não · Lib: nenhuma

Assinatura
GetAccountTypes(): Record<string, AccountTypeDefinition>
Lua
local types = exports['ai-core']:GetAccountTypes() -- table indexada pelo nome da conta

Parâmetros

Nenhum.

Retorno

Record<string, AccountTypeDefinition>: uma cópia indexada pelo nome da conta (cash, bank...). Cada valor tem label (mostrado aos jogadores), start (o que um personagem novo recebe) e allowNegative. Veja AccountTypeDefinition.

Exemplo

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

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

// A tela da carteira lista cada conta com o rótulo e o saldo.
onClientCallback("myscript:wallet", (source) => {
  const rows = Object.entries(core.GetAccountTypes()).map(([name, type]) => ({
    name,
    label: type.label,
    balance: core.GetMoney(source, name) ?? 0,
  }));
  return { ok: true, rows };
});

Nesta página