Documentación

Documentación de Clothing store

Una tienda de ropa con conjuntos guardados, vestuarios de empresa y un editor que pone precio al catálogo desde el propio juego. Todos los componentes y todos los props, comprados prenda a prenda o como conjunto entero, con un registro en el servidor que impide que nadie lleve puesto lo que no ha pagado.

  • ESX
  • QBCore
  • vRP
  • Standalone
  • oxmysql
01

Instalación

  1. Coloca el recurso

    Descarga el script desde tu cuenta Tebex, copia la carpeta avenida_clotheshops/ en tu directorio de recursos y añade ensure avenida_clotheshops a la config del servidor, después de ensure oxmysql.

  2. Ejecuta el SQL

    Ejecuta la sección [A] de INSTALL.sql en tu base de datos. La sección [B] es condicional, la cabecera del archivo dice cuándo la necesitas.

  3. Concede los permisos de admin

    Añade add_ace group.admin avenida_clotheshops.admin allow y add_ace group.admin avenida_clotheshops.vip allow a la config del servidor. El primero abre el editor de catálogo dentro del juego, el segundo desbloquea lo que hayas reservado a la lista VIP.

  4. Pon precio al catálogo desde el juego

    Pon Config.DevMode.Enabled = true, entra en una tienda y abre el editor. Fija precios, oculta lo que no vendes, reserva lo que pertenece a un trabajo. Todo acaba en config/clothes_overrides.lua. Vuelve a apagar DevMode cuando termines, se comprueba otra vez en el servidor en cada guardado.

  5. Verifica las integraciones

    Pon Config.Debug = true, reinicia y lee la consola: una línea por categoría de bridge nombra el target elegido. Config.Debug solo controla los logs, no es el interruptor del editor.

02

Configuración

Poner precio a una sección de tres formas distintas

Cada tienda declara sus secciones, y cada sección su modo de precio. Una tarifa única para toda una sección, un multiplicador que encarece los drawables siguientes, o una tabla cuando solo un puñado de prendas merece su propio precio.

lua
-- config/clothes_shops.lua
categories = {
    tops = {
        enabled = true,
        price   = { mode = 'fixed', base = 300 },
    },
    pants = {
        enabled = true,
        -- price = base + index * mult
        price   = { mode = 'multiplier', base = 100, mult = 2 },
    },
    mask = {
        enabled = true,
        price   = { mode = 'table', map = { [12] = 900, [45] = 1500 } },
        -- only these drawables are offered
        whitelist = { 12, 45, 51 },
    },
}
03

Exports

Client

  • GetSkinData
    exports['avenida_clotheshops']:GetSkinData()

    El conjunto que lleva puesto el jugador, componente a componente, props incluidos. Es lo que la tienda escribe al comprar, así que siempre coincide con lo que muestra el armario.

  • ApplySkin
    exports['avenida_clotheshops']:ApplySkin(data, ped)

    Aplica una apariencia completa a un ped. Poner un conjunto vacía la ranura de decoraciones, así que esta llamada vuelve a poner después el trabajo de barbería y de tatuaje en vez de dejar la piel desnuda.

  • ApplyClothing
    exports['avenida_clotheshops']:ApplyClothing(data, ped, temporary)

    Cambia la ropa y nada más. Con temporary en true el conjunto vive solo durante la sesión, que es como debe comportarse un uniforme que entrega un trabajo.

Server

  • GetBagStorage
    exports['avenida_clotheshops']:GetBagStorage(sex, drawable) --> { weight, slots } | nil

    La capacidad que da un drawable de mochila, peso y ranuras, o nil cuando ese drawable no lleva nada. Llámalo desde tu recurso de inventario para que una mochila comprada guarde algo de verdad.

04

Recetas

Abrir una tienda con su impuesto y su descuento

Una tienda es una sola entrada de config. Lleva su nombre visible, su método de pago, su símbolo de moneda, un impuesto y un descuento opcionales sobre el total del carrito, y las secciones que ofrece. Mantén la clave estable: es el id de tienda que se guarda dentro de los conjuntos, y cambiarle el nombre después de que la gente haya comprado allí les rompe los datos.

lua
-- config/clothes_shops.lua
Config.Clothes.Shops[22] = {
    name       = 'Ponsonbys - Rockford Hills',
    payment    = 'bank',
    currency   = '$',
    tax        = 0.20,        -- +20% on the cart
    discount   = 0.00,
    outfitMode = true,
    blip = { sprite = 73, color = 4, scale = 0.7, coords = vec3(-708.2, -152.2, 37.4) },
    categories = {
        tops  = { enabled = true, price = { mode = 'fixed', base = 900 } },
        shoes = { enabled = true, price = { mode = 'fixed', base = 450 } },
    },
}

Reservar un uniforme para un trabajo

Una pieza restringida se le oculta a quien no pasa la comprobación, así que un civil nunca ve la chaqueta de policía en la cuadrícula. Los vestuarios de empresa van más lejos: el jefe edita una lista compartida y cada miembro la lleva sin pagar, que es lo que necesitas para un recluta en su primer turno.

lua
-- config/clothes_overrides.lua, or write it from the in-game editor
Overrides['tops'] = {
    [56] = { job = 'police', label = 'LSPD jacket' },
    [12] = { hidden = true },
    [31] = { restricted = true },   -- ACE permission
}

Apagar el registro de propiedad

Está activo por defecto y es lo que impide que un cliente manipulado lleve el catálogo gratis. Apágalo solo si otro recurso tuyo viste a los jugadores con prendas que nunca compraron y prefieres no registrarles esas compras. Los personajes que ya existen se inicializan con lo que llevan puesto, así que activarlo más tarde no le quita nada a nadie.

lua
-- config/clothes.lua
Config.Clothes.RequireOwnership = false

-- how far from a store the server still accepts a purchase
Config.Clothes.PurchaseRange = 30.0

-- saved outfits per character, enforced server side
Config.Clothes.MaxOutfits = 30
Config.Clothes.MaxOutfitsRestricted = 50

Redibujar decoraciones desde tu propio script

Aplicar un conjunto completo vacía la ranura de decoraciones del ped, que comparte todo el servidor. Si tu script viste a un jugador, lee antes lo que es de este recurso y devuélvelo después, o los tatuajes y la hair base se van con el cambio.

lua
local hairbase = exports['avenida_clotheshops']:GetHairbase()
local tattoos  = exports['avenida_clotheshops']:GetTattoos()

-- your own clothing work here

if hairbase then
    AddPedDecorationFromHashes(PlayerPedId(), hairbase.c, hairbase.t)
end
for _, dec in ipairs(tattoos) do
    AddPedDecorationFromHashes(PlayerPedId(), dec.c, dec.t)
end
05

Preguntas

Un jugador dice que ha perdido ropa que tenía

Mira Config.Clothes.RequireOwnership. El registro da por pagado lo que un personaje ya lleva puesto la primera vez que lo ve, así que activarlo no le quita el vestuario a nadie. Lo que sí rechaza es una escritura de una prenda que no tenga una compra detrás, que es justo lo que manda un cliente manipulado. Si un recurso tuyo viste a los jugadores con prendas que nunca compraron, registra esas compras o pon el flag a false.

El editor de catálogo no se abre

Necesita dos cosas a la vez: el permiso ACE avenida_clotheshops.admin y Config.DevMode.Enabled = true. Config.Debug es otro interruptor distinto y solo controla los logs. Cada guardado se vuelve a comprobar en el servidor, así que darte el permiso en el juego no basta por sí solo.

La misma chaqueta aparece varias veces

Es GTA. El juego repite un drawable en varios índices, y la mayoría de las tiendas los listan todos. Aquí los drawables fantasma se filtran, así que si aún ves un duplicado suele ser un pack de ropa que trae dos veces el mismo asset. Oculta el que sobra desde el editor dentro del juego: acaba en config/clothes_overrides.lua.

El pelo atraviesa un casco

El corte se declara por item, así que un casco o una máscara que hayas añadido tú aún no tiene regla. Configura desde el editor de catálogo cómo trata el pelo, y recuerda que existe la preferencia del jugador: quien quiera conservar su peinado puede decirlo, y su elección gana al corte automático.

¿Las fotos de los conjuntos necesitan instalar algo?

Necesitan screenshot-basic, y solo para eso. Es la única integración opcional de la tabla de requisitos cuya ausencia nota el jugador: sin ella los conjuntos guardados funcionan exactamente igual, pero la lista muestra nombres en vez de vistas previas.

¿Qué frameworks soporta realmente?

QBCore, ESX y vRP, más un modo standalone que no necesita framework alguno y una rama custom en bridges/framework.lua para cualquier otra cosa. La detección se hace al arrancar y sondea el export real. Qbox y ox_core no tienen rama dedicada: pasan por la vía standalone o custom, no por un target probado.

¿Puedo usarlo junto a avenida_barber y avenida_tattoo?

Sí, están hechos para eso. Este es el más invasivo de los tres, ya que aplicar un conjunto vacía la ranura de decoraciones, así que vuelve a poner lo que es de los otros dos tras cada cambio. Lo que no debes hacer es usar los recursos sueltos y el pack avenida_skin a la vez. El recurso detecta el solape y lo dice en consola al arrancar.

¿Cuánto cuesta cuando no hay nadie comprando?

0.00ms. Los puntos de interacción comparten un hilo que baja a un segundo cuando no hay nadie cerca, los blips se crean una vez, y cada hilo de sesión muere al salir. El debounce de vista previa solo existe mientras hay un menú abierto, y se puede ajustar para máquinas más flojas.

Carrito
Spirit RP
Discord