
Shops
Sistema de tiendas para el inventario estándar y ox_inventory: tiendas con cesta, armerías, mercado negro rotativo, ofertas del día, vendedores NPC y un editor de tiendas en el juego.
- ESX Legacy (
es_extended) - oxmysql
- Inventario: inventario estándar de ESX u ox_inventory (se detecta al iniciar)
- Opcional: ox_target
Funciones
- Tres tipos de tienda: tienda con cesta, armería y mercado negro. Se paga con tarjeta o en efectivo, en el mercado negro con dinero negro.
- El servidor comprueba precios, total, peso y distancia. Stock solo en tiendas compradas. Reglas por tipo de tienda, tienda u objeto.
- Tiendas en venta: los jugadores compran una tienda, fijan precios, traen mercancía del mayorista y gestionan la caja.
- Mercado negro rotativo con ubicaciones, surtido y precios cambiantes, además de ofertas del día en las tiendas normales.
- Editor de tiendas en el juego con modelo de NPC, escenario, marcador con vista previa en directo y blip propio.
- Logs de Discord por compra y estadísticas en directo en Discord.
Instalación
- Pon la carpeta
off_shopsen tu carpetaresources. - Todos los objetos de
config/settings/config.items.luadeben existir en tu inventario – ESX: tablaitems, ox_inventory:ox_inventory/data/items.lua. Las armas (weapon_…) no necesitan entrada con ESX. - En el
server.cfg– después de ESX, oxmysql y tu inventario:
ensure oxmysql
ensure es_extended
ensure ox_inventory
ensure off_shopsLas tablas se crean automáticamente y se completan en las actualizaciones.
Configuración
config/settings/config.lua
| Opción | Predeterminado | Descripción |
|---|---|---|
serverInfo.name | 'OFF SCRIPTS' | Nombre del servidor, se muestra en la interfaz en lugar de «OFF SCRIPTS» |
serverInfo.locale | 'de' | Idioma: de, en, pl, fr, es, it o nl |
serverInfo.color | { 155, 89, 255 } | Color de la UI (RGB) |
serverInfo.design | 3 | Diseño de la interfaz: 1 = Clásico, 2 = Ticket, 3 = Storefront |
blur | true | Fondo desenfocado mientras la tienda está abierta. El editor se mantiene nítido (vista previa) |
useTarget | false | true = ox_target en lugar de E |
pedSpeech | true | El NPC saluda, se despide y da las gracias con voz |
purchase.maxPerItem | 25 | Cantidad máxima por artículo y compra |
deals.enabled / count / discountPercent | false / 2 / 20 | Ofertas del día (solo tiendas normales, sin armas): activar/desactivar, cantidad, descuento en porcentaje |
marker.color / marker.alpha | { 155, 89, 255 } / 150 | Color predeterminado y opacidad de los marcadores |
editor.command / editor.groups | 'shopeditor' / { 'projektleitung' } | Comando y grupos de ESX para el editor |
stats.enabled / updateMinutes | true / 10 | Estadísticas en directo en Discord, actualización en minutos |
blackmarket.rotation / activeLocations | 'day' / 1 | Cambio del mercado negro ('day', 'week', 'month') y cuántos hay a la vez |
blackmarket.itemsPerCategory / priceVariancePercent | 2 / 15 | Artículos por categoría en el periodo, variación de precio en porcentaje |
shopTypes | normal, weapon, blackmarket | Por tipo label, ped (vendedor), uiColor (color de UI propio), blip y rules |
Reglas (rules) hay por tipo de tienda, tienda u objeto: jobs, blockedJobs, minGrade y hours = { from, to } (hora del juego, 22–5 = 22:00–04:59).
config/settings/config.locations.lua – Ubicaciones
{ type = 'normal', label = 'LTD Davis', interactionType = 'ped', position = vec4(-47.02, -1758.23, 29.42, 45.05), categories = { 'food', 'drinks', 'tools' } },
{ type = 'blackmarket', interactionType = 'ped', position = vec4(14.2280, -1104.0475, 29.7970, 340.0), categories = { 'weapons', 'illegal' } },| Campo | Descripción |
|---|---|
type | 'normal', 'weapon' o 'blackmarket' |
interactionType | 'ped' (NPC, vec4 con orientación) o 'marker' |
categories | Qué categorías vende la tienda |
price | Opcional: precio de compra · sin price la tienda no está en venta |
label / rules / blip = false | Opcional: nombre propio, reglas propias o sin icono en el mapa |
Las ubicaciones con type = 'blackmarket' son posibles sitios del mercado negro – de ellas, activeLocations están activas a la vez.
Categorías y objetos
food = { label = 'Essen', items = { 'bread', 'kebab', 'wrap' } }, -- categoría
{ name = 'water', label = 'Wasser', price = 10 }, -- objeto- Opcional por objeto:
max(cantidad máxima propia),image(imagen propia),rules(reglas propias). weapon_…se trata como arma: se compra de una en una, con 42 balas en el inventario de ESX, no por duplicado.- Imágenes: ESX carga
web/dist/assets/items/<name>.png, ox_inventory usa las suyas. Pon las imágenes de armas que falten enweb/dist/assets/weapons/<name>.png.
config/functions.lua
| Función | Para qué |
|---|---|
Notify(message, type) | Notify propio · Servidor: Notify(source, message, type) |
HelpNotify(text) | Texto de ayuda en el vendedor o el marcador |
Logs de Discord
Los webhooks los pones en config/settings/config.server.lua (solo en el servidor): purchases registra cada compra, stats son las estadísticas en directo. Una url vacía ('') desactiva el log.
Idiomas
Todos los textos están en config/locales/<idioma>.json. Para un idioma propio, copia un archivo, tradúcelo y ajusta locale – deja dentro los placeholders como %s y {total}.
En el juego
Pulsa E en el vendedor o el marcador (o usa ox_target), elige artículos y paga. En la tienda hay una cesta, en la armería y en el mercado negro eliges un artículo.
Editor de tiendas (/shopeditor)
- A la izquierda están todas las tiendas del editor. Las tiendas de la config no aparecen ahí, esas las cambias en
config/settings/config.locations.lua. - Nueva crea una tienda en tu posición actual, Editar abre una existente.
- Puedes ajustar tipo, nombre, categorías, NPC o marcador, posición con orientación y blip.
- NPC: Elige un modelo de una lista con imágenes de todos los peds de GTA (búsqueda y categorías), además de escenario y orientación, todo con vista previa en directo en el juego. Un ped addon lo eliges con el nombre exacto del modelo en la búsqueda. Predeterminado = vendedor de
shopTypes. - Marcador: Tipo, tamaño, distancia al suelo, rotación, color, opacidad y movimiento con vista previa en directo en el juego.
- Blip: activado o no, opcionalmente con icono y color propios. Si no, se usa el blip de
shopTypes. - Mientras el editor está abierto, te mueves con WASD y miras alrededor manteniendo pulsado el botón derecho. Luego pulsa Tomar posición.
- Tras Guardar, el cambio se aplica al instante para todos los jugadores. Un mercado negro del editor es fijo y vende todos los artículos de sus categorías.
Tiendas en venta
Si una tienda se puede comprar lo ajustas con price en config.locations.lua para las tiendas de la config, y en el editor para las tiendas del editor (grupo Propiedad: En venta, Precio de compra). El mercado negro nunca está en venta. Las tiendas sin dueño venden como siempre, sin stock.
Opción (ownership) | Por defecto | Descripción |
|---|---|---|
enabled | true | Tiendas en venta sí/no. No = todo como sin la función |
maxPerPlayer | 1 | Cuántas tiendas puede tener un jugador |
startStock / maxStock | 20 / 200 | Stock inicial por artículo tras la compra / stock máximo por artículo |
priceRange.min / max | 0.8 / 1.5 | Precio de venta permitido = precio base × min a max |
wholesaleFactor | 0.6 | Precio mayorista = precio base × factor |
sellBackPercent | 60 | Recompra del servidor en % del precio de compra |
van / orderMaxUnits / orderMinutes | 'speedo' / 300 / 20 | Furgoneta, unidades máx. por viaje, límite de tiempo en minutos |
vanSpawn | vec4(...) | Punto de spawn de la furgoneta, el jugador se teletransporta allí |
refundPercent | 0 | Reembolso en % si la entrega falla o se cancela |
wholesalers | 3 × vec3 | Mayoristas, se usa el más cercano a la tienda |
En el juego: En una tienda en venta, E abre primero una elección entre Comprar y Gestión, con una cámara sobre el vendedor si hay un NPC. Si la tienda es de otra persona, se abre directamente la tienda. Sin dueño, Gestión lleva a la oferta, como dueño a la gestión con Resumen (caja, ventas de hoy/7 días/total, gráfico, artículos casi agotados), Almacén, Precios, Pedido y Caja (sacar/ingresar en efectivo o cuenta, historial, vender la tienda). Los clientes pagan a la caja y solo pueden comprar lo que hay en stock.
Entrega: Elige la mercancía, el coste sale de la caja. Te teletransportan al punto vanSpawn y te sientan en la furgoneta – ve al mayorista, E en el marcador (cargar), vuelve y aparca la furgoneta en el marcador, luego ve al vendedor y pulsa E. Solo entonces entra en el almacén. Si la furgoneta se destruye, se acaba el tiempo o sales del servidor, la mercancía se pierde (reembolso según refundPercent). Tras reiniciar el servidor, una entrega abierta se reembolsa entera.
Log de Discord: webhook ownership en config/settings/config.server.lua (compra, venta, entregas, retiradas/ingresos). Liberar en el editor deja la tienda libre (almacén y caja se pierden).
Problemas frecuentes
| Problema | Solución |
|---|---|
[ERROR] en la consola del servidor | El script comprueba la instalación al iniciar. Lee el mensaje, corrige el fallo y reinicia el script. |
| «Este artículo no es válido» | Falta el objeto en el inventario (ESX: tabla items, ox_inventory: items.lua). |
| ox_inventory no se detecta | ensure ox_inventory debe estar antes de off_shops. |
| El mercado negro está cerrado | Por defecto solo de 22 a 5 h, hora del juego (rules.hours). |
| El mercado negro no está | Solo activeLocations ubicaciones están activas – las demás en el próximo cambio. |
| Mercado negro: «Dinero insuficiente» | El mercado negro solo acepta dinero negro (black_money). |
/shopeditor no se abre | Tu grupo de ESX debe estar en editor.groups. |
| «El modelo de NPC … no existe» | Comprueba el nombre del modelo, p. ej. mp_m_shopkeep_01. Los peds addon tienen que estar en stream. |
¿Aún no lo has comprado?
Ver Shops en la tienda