Final project: a 24/7 store with QBCore · Lesson 2/4 · 10 min

The client: target and product menu

fxmanifest, config with the catalog and a client that sets up the qb-target zone and opens the menu.

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 = 'Water', precio = 5 },
  { item = 'sandwich',     label = 'Sandwich', 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 = 'Buy' } },
    distance = 2.0,
  })
end)

RegisterNetEvent('tienda:client:abrir', function()
  local menu = { { header = '24/7 Store', 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

Notice: the client only sends the NAME of the item; the price is NOT sent (the server decides it from Config). That way a cheater can't fake the price.

Practice what you learned

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.

Challenge: code it yourself

Add a third product to the catalog and check that it appears in the menu.

Write it yourself in your editor (VS Code) and test it on your server. You learn here by doing it, not by copying.

See hint

Just add another row { item='...', label='...', precio=... } to Config.Productos.

Escribe aquí tu solución:

How was this lesson?