Proyecto final: una tienda 24/7 con QBCore · Lección 2/4 · 10 min

El cliente: target y menú de productos

fxmanifest, config con el catálogo y un cliente que pone la zona qb-target y abre el menú.

lua
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
shared_scripts { 'config.lua' }
client_scripts { 'client.lua' }
server_scripts { 'server.lua' }
dependency 'qb-core'

fxmanifest.lua

lua
-- config.lua
Config = {}
Config.Pos = vector3(25.7, -1347.3, 29.5)
Config.Productos = {
  { item = 'water_bottle', label = 'Agua', precio = 5 },
  { item = 'sandwich',     label = 'Bocadillo', precio = 8 },
}

config.lua

lua
-- client.lua
local QBCore = exports['qb-core']:GetCoreObject()

CreateThread(function()
  exports['qb-target']:AddBoxZone('tienda_247', Config.Pos, 1.5, 1.5, {
    name = 'tienda_247', heading = 0,
  }, {
    options = { { type = 'client', event = 'tienda:client:abrir', icon = 'fas fa-basket-shopping', label = 'Comprar' } },
    distance = 2.0,
  })
end)

RegisterNetEvent('tienda:client:abrir', function()
  local menu = { { header = 'Tienda 24/7', isMenuHeader = true } }
  for _, p in ipairs(Config.Productos) do
    menu[#menu + 1] = {
      header = p.label,
      txt = ('$%s'):format(p.precio),
      params = { event = 'tienda:client:comprar', args = { item = p.item } },
    }
  end
  exports['qb-menu']:openMenu(menu)
end)

RegisterNetEvent('tienda:client:comprar', function(data)
  TriggerServerEvent('tienda:server:comprar', data.item)
end)

client.lua

Fíjate: el cliente solo manda el NOMBRE del item; el precio NO se manda (lo decide el servidor desde Config). Así un tramposo no puede falsear el precio.

Practica lo aprendido

0/3
Rellena los huecos

Completa la primera línea del cliente que obtiene el objeto del core de QBCore.

1local QBCore = exports['qb-core']:()
Pista

Es la forma estándar de tener el objeto QBCore disponible en client y server.

Rellena los huecos

El cliente abre el menú; completa lo que se manda al servidor al elegir un producto. Recuerda: solo el NOMBRE del item.

1RegisterNetEvent('tienda:client:comprar', function(data)
2 TriggerServerEvent('tienda:server:comprar', )
3end)
Pista

No se manda el precio, solo el identificador del item que llega en data.

Corrige el error

Este cliente manda también el precio al servidor. Arréglalo: el cliente solo debe mandar el nombre del item.

Este código tiene un fallo:

1RegisterNetEvent('tienda:client:comprar', function(data)
2 TriggerServerEvent('tienda:server:comprar', data.item, data.precio)
3end)

Reescríbelo corregido:

Pista

Quita data.precio de la llamada; el servidor ya conoce el precio desde Config.

Reto: prográmalo tú

Añade un tercer producto al catálogo y comprueba que aparece en el menú.

Escríbelo tú en tu editor (VS Code) y pruébalo en tu servidor. Aquí se aprende haciéndolo, no copiando.

Ver pista

Solo añade otra fila { item='...', label='...', precio=... } a Config.Productos.

Escribe aquí tu solución:

¿Qué tal esta lección?