Saltearse al contenido

Tu primer recurso de BS19

Esta guía construye un recurso pequeño desde cero: un comando /checkin que da a un superviviente una botella de agua, como mucho una vez por hora. Lleva unos 15 minutos. Necesitas un servidor BS19 en marcha, acceso a sus archivos y a la consola de txAdmin, y un editor de texto (VS Code va muy bien).

Cuando funcione, Escribir un recurso sobre bs_core muestra los siguientes pasos: código de cliente, callbacks y las trampas que conviene evitar.

En la carpeta resources de tu servidor, crea una carpeta llamada [local] (los corchetes importan: la convierten en una categoría, no en un recurso) y dentro una carpeta llamada bs_checkin. Guarda tus propios recursos en [local] para que las actualizaciones del framework nunca los sobrescriban.

resources/[local]/bs_checkin/
├── fxmanifest.lua
├── config.lua
└── server.lua

El nombre de la carpeta es el nombre del recurso. Empiézalo por bs_ para que no choque con otro script.

Todo recurso de FiveM necesita este archivo. Le dice al servidor qué archivos cargar y en qué lado.

fx_version 'cerulean'
game 'gta5'
lua54 'yes'
name 'bs_checkin'
description 'My first BS19 resource'
shared_scripts {
'@bs_core/shared/sh_bridge.lua', -- gives you BSB (commands, callbacks)
'config.lua',
}
server_scripts { 'server.lua' }
dependencies { 'bs_core', 'bs_inventory' }

La línea @bs_core/shared/sh_bridge.lua carga el puente de BS19 en tu recurso. Sin ella, BSB no existe y el archivo del servidor falla.

Pon en una sola tabla todos los valores que un dueño de servidor podría querer cambiar, así nadie tiene que tocar tu código.

Checkin = {
item = 'water_bottle', -- any item name from bs_inventory's item list
amount = 1,
cooldown = 3600, -- seconds between two check-ins (1 hour)
}
local lastCheckin = {} -- [charId] = os.time() of the last check-in
local function notify(src, kind, message)
TriggerClientEvent('bs:ui:notify', src, { type = kind, message = message })
end
BSB.RegisterCommand('checkin', nil, 'Daily survivor check-in', {}, function(src)
if src == 0 then return print('Run /checkin in game, not in the console.') end
local p = exports.bs_core:GetPlayerSummary(src)
if not p then return notify(src, 'error', 'Pick a character first.') end
local now = os.time()
local last = lastCheckin[p.charId]
if last and now - last < Checkin.cooldown then
local minutes = math.ceil((Checkin.cooldown - (now - last)) / 60)
return notify(src, 'error', ('Come back in %d min.'):format(minutes))
end
local ok, reason = exports.bs_inventory:GiveItem(src, Checkin.item, Checkin.amount)
if not ok then return notify(src, 'error', 'No room: ' .. tostring(reason)) end
lastCheckin[p.charId] = now
notify(src, 'success', ('Welcome back, %s. Here is some water.'):format(p.firstName))
end)

Qué hace, línea por línea:

  • BSB.RegisterCommand crea el comando de chat. El nil significa que cualquiera puede usarlo; pon ahí una ACE como 'bs.admin' para limitarlo al staff.
  • GetPlayerSummary devuelve nil mientras el jugador sigue en la pantalla de personajes, así que compruébalo antes que nada.
  • La espera se guarda por personaje (charId), no por jugador, así que un segundo personaje tiene su propio check-in. Se reinicia al reiniciar el recurso, lo cual basta para un primer recurso.
  • Los objetos siempre pasan por exports.bs_inventory:GiveItem. Devuelve false y un motivo cuando el inventario está lleno. Nunca escribas tú en la base de datos.

Añade esta línea al final de server.cfg, después de los recursos de BS19:

ensure bs_checkin

Luego, en la consola en vivo de txAdmin (no hace falta reiniciar el servidor):

refresh
ensure bs_checkin

refresh hace que el servidor vea la carpeta nueva. La consola debería mostrar Started resource bs_checkin. Cuando edites un archivo más adelante, basta con ensure bs_checkin para recargarlo.

  1. Entra al servidor y elige un personaje.
  2. Pulsa T, escribe /checkin y pulsa Enter. Recibes una notificación verde y una botella de agua en el inventario (I).
  3. Escribe /checkin otra vez. Recibes un mensaje rojo “Come back in 60 min.”.
Lo que vesPor quéSolución
Couldn't find resource bs_checkinEl servidor no ha visto la carpeta o el nombre no coincideEjecuta refresh y comprueba que la carpeta se llama exactamente bs_checkin
attempt to index a nil value (global 'BSB')Falta la línea del puenteRevisa la línea @bs_core/shared/sh_bridge.lua en fxmanifest.lua
No such export GetPlayerSummarybs_core aún no ha arrancadoDeja ensure bs_checkin debajo de los recursos de BS19 en server.cfg
/checkin no hace nada, sin errorSigues en la pantalla de personajes o el comando nunca se registróElige un personaje y busca una línea roja [bs_checkin] en la consola
“No room: …”Tu inventario está lleno o pesa demasiadoSuelta algo y vuelve a intentarlo

Cualquier error rojo en la consola también indica el archivo y la línea. Corrígelo, ejecuta ensure bs_checkin de nuevo y vuelve a probar.

  • Cambia item a bandage en config.lua y ejecuta ensure bs_checkin. Sin tocar código.
  • Da también algo de dinero: exports.bs_core:AddMoney(src, 'cash', 25, 'checkin').
  • Da XP: exports.bs_core:AddXP(src, 10, 'checkin').
  • Mira las llamadas disponibles en Resumen de exports y eventos.