Experiencia de compra¶
Como funciona la tienda desde el punto de vista del jugador.
1. Localizacion¶
La tienda se presenta con hasta 3 elementos opcionales:
- Blip en el mapa — color segun tipo (civil / business / illegal).
- Marker en el suelo — animado, visible a 15 metros por defecto.
- NPC tendero — con escenario (
WORLD_HUMAN_STAND_IMPATIENT) para que no parezca un maniqui.
Si una tienda es business o illegal y el jugador no cumple la restriccion, no vera ni marker ni ped (pero si ve el blip, configurable).
2. Abrir la tienda¶
Cuando el jugador esta a < 2 metros del marker, aparece la indicacion de pulsar E (configurable en Config.Marker.InteractionKey). El cliente:
- Llama a la callback
nb-shops:getShopData(shopId). - Recibe
{ shop, items, imageMap }. - Abre la NUI y pone focus.
imageMaptraduce cadaitem_namea la URL NUI final (nui://<inventory>/images/<item>.png), respetando los overrides declient.imagedefinidos en tu inventario.
3. Navegar¶
- Sidebar — lista de categorias definidas al crear la tienda.
- Grid — items de la categoria seleccionada. Cada card tiene icono, nombre, precio y stock disponible.
- Detalle — click en un item para ver su descripcion y elegir cantidad.
4. Carrito¶
- Se puede sumar N items antes de pagar.
- El carrito acumula por metodo de pago cuando hay varios (ej. la tienda acepta
cashybank— el jugador elige al checkout). - Si un item usa otro item como moneda (ej. 1
gold_coinpor unidad), el carrito detalla la cantidad de monedas requeridas.
5. Checkout¶
Pulsar "Pagar" envia:
El servidor valida en este orden:
- Acceso —
civil/businessconBridge.GetJob(src)/illegalconBridge.GetGang(src). - Stock — para cada item no infinito,
current_stock >= count. - Fondos —
Bridge.GetMoney(src, paymentMethod)si es cash/bank,Bridge.HasItem(src, item_price, item_price_amount * count)si es item-como-moneda. - Capacidad —
Bridge.CanCarry(src, item_name, count)(lo que soporte el inventario).
Si todo OK:
Bridge.RemoveMoney(oBridge.RemoveItempara item-moneda).Bridge.AddItemcon el item comprado.- Actualiza
current_stocken BD. - Notificacion de exito al jugador.
- Si alguien mas esta dentro de la tienda, le llega la actualizacion de stock.
Si algo falla, la compra se anula completa (no se descuenta nada) y el jugador recibe { success = false, message = Locale('<razon>') }.
6. Anti-bypass¶
- Doble validacion — el client no envia "ya pague": envia un cart y el server calcula el total.
- Permisos — validados en el servidor aunque el client marker este escondido.
- Stock atomico — el
UPDATE ... WHERE current_stock >= ?evita compras simultaneas sobre el ultimo unit.
7. Cerrar la UI¶
- ESC — cierra.
- Salirse del marker a mas de
Config.Marker.InteractionDistance * 2— cierra automaticamente. - Reiniciar el recurso — se envia un
NUI: closeforzado al restart.