Eventos de cliente
Los eventos de cliente se disparan en el juego de un solo jugador: el comprador, el vendedor, el que ha sido superado en una puja, el atracador… Nunca se envían a todo el servidor. Escúchalos en client/handlers.lua (los handlers ya están ahí, vacíos) o desde cualquier script de cliente tuyo:
AddEventHandler('sl-marketplace:onSaleMade', function(data) PlaySoundFrontend(-1, 'WAYPOINT_SET', 'HUD_FRONTEND_DEFAULT_SOUNDSET', true)end)Resumen
Sección titulada «Resumen»| Evento | Quién lo recibe | Hook del servidor del mismo momento |
|---|---|---|
onPurchaseCompleted |
Comprador | OnSaleCompleted |
onSaleMade |
Vendedor (si está conectado) | OnSaleCompleted |
onAuctionWon |
Ganador (si está conectado) | OnAuctionEnded |
onListingCreated |
Vendedor | OnListingCreated |
onListingCancelled |
Vendedor | OnListingCancelled |
onListingBumped |
Vendedor | OnListingBumped |
onBidPlaced |
Quien puja | OnBidPlaced |
onOutbid |
El que ha sido superado | OnBidPlaced |
onMailboxClaimed |
Quien recoge | OnMailboxClaimed |
onMessageReceived |
Destinatario de un mensaje del chat | OnMessageSent |
onRefundStatusChanged |
Comprador y vendedor | OnRefundRequested / Approved / Rejected |
onDeliveryArrived |
Comprador | OnDeliveryCompleted |
onDeliveryResult |
Comprador | OnDeliveryCompleted / Failed / Robbed |
onDeliveryRobbed |
Atracador | OnDeliveryRobbed |
onInPersonTradeStarted |
Comprador y vendedor | — |
onInPersonMeetUpdated |
Comprador y vendedor | OnMeetupStatusChanged |
onInPersonTradeCompleted |
Comprador y vendedor | OnInPersonTradeCompleted |
onInPersonTradeCancelled |
Comprador y vendedor | OnInPersonTradeCancelled |
onSkillCheckStarted |
Quien juega el minijuego | — |
onSkillCheckPhase |
Quien juega el minijuego | — |
onSkillCheckFinished |
Quien juega el minijuego | — |
Todos los nombres empiezan por sl-marketplace:, por ejemplo sl-marketplace:onSaleMade.
Compras y ventas
Sección titulada «Compras y ventas»onPurchaseCompleted
Sección titulada «onPurchaseCompleted»Quién: el comprador. Cuándo: justo después de pagar (OnSaleCompleted). En las compras por repartidor y en persona settlementPending es true: el objeto todavía no ha llegado.
| Campo | Significado |
|---|---|
item, itemLabel, quantity |
Lo comprado |
price / basePrice |
Precio del anuncio, sin extras |
grossPaid |
Total pagado |
platformFee, deliveryFee, insuranceFee |
Comisiones |
deliveryMode, listingType, sellerName |
Detalles |
stage, settlementPending |
'committed' / true por repartidor y en persona, 'settled' / false en el resto |
listingId |
ID del anuncio |
Ejemplo
AddEventHandler('sl-marketplace:onPurchaseCompleted', function(data) PlaySoundFrontend(-1, 'PURCHASE', 'HUD_LIQUOR_STORE_SOUNDSET', true)end)Prueba: compra cualquier anuncio (solo: /markettest listing mailbox fixed bread 50).
onSaleMade
Sección titulada «onSaleMade»Quién: el vendedor, solo si está conectado. Cuándo: alguien compra uno de sus anuncios.
| Campo | Significado |
|---|---|
buyerName |
Comprador |
item, itemLabel, quantity |
Lo vendido |
price / basePrice, grossPaid, platformFee, sellerPayout |
Dinero |
deliveryMode, listingType |
Detalles |
stage, settlementPending |
Como en onPurchaseCompleted |
listingId |
ID del anuncio |
Prueba: dos jugadores; B compra un anuncio de A mientras A está conectado.
onAuctionWon
Sección titulada «onAuctionWon»Quién: el ganador, solo si está conectado. Cuándo: termina una subasta que va ganando (OnAuctionEnded), hasta 30 s después de la hora de fin.
| Campo | Significado |
|---|---|
item, itemLabel, quantity |
Lo que ganó |
winningBid / grossPrice / finalPrice |
Puja ganadora |
platformFee, sellerPayout |
Dinero |
sellerName, listingType, deliveryMode, meetupPoint |
Detalles |
stage |
'settled' |
listingId |
ID del anuncio |
Prueba: /markettest listing mailbox auction bread 100, puja y espera 5 minutos.
Anuncios y pujas
Sección titulada «Anuncios y pujas»onListingCreated
Sección titulada «onListingCreated»Quién: el vendedor. Cuándo: se ha publicado su anuncio.
Campos: listingId, item, itemLabel, itemMetadata, quantity, price, listingType, deliveryMode, featured.
Prueba: publica cualquier objeto desde el marketplace.
onListingCancelled
Sección titulada «onListingCancelled»Quién: el vendedor. Cuándo: se cancela su anuncio, por él o por un administrador.
Campos: listingId, item, itemLabel, quantity, price, listingType, cancellationType ('owner' o 'admin').
Prueba: cancela uno de tus anuncios.
onListingBumped
Sección titulada «onListingBumped»Quién: el vendedor. Cuándo: sube (bump) un anuncio.
Campos: listingId, item, itemLabel, cost, bumpedAt.
Prueba: sube uno de tus anuncios.
onBidPlaced
Sección titulada «onBidPlaced»Quién: quien puja. Cuándo: se acepta su puja, o la puja automática puja por él (bidType = 'proxy_auto').
Campos: listingId, item, itemLabel, amount, previousBid, bidType, sellerName.
Prueba: puja en una subasta de prueba.
onOutbid
Sección titulada «onOutbid»Quién: el jugador que iba ganando. Cuándo: alguien hace una puja más alta (a mano o automática).
| Campo | Significado |
|---|---|
listingId, item, itemLabel |
La subasta |
previousBid |
Su puja, ya superada |
newBid |
La nueva puja más alta |
bidderName |
Quién le superó |
bidType |
'manual' o 'proxy_auto' |
Ejemplo: sonido y destello en pantalla
AddEventHandler('sl-marketplace:onOutbid', function(data) PlaySoundFrontend(-1, 'LOSER', 'HUD_AWARDS', true) AnimpostfxPlay('FocusOut', 800, false)end)Prueba: dos jugadores pujan en la misma subasta; el primero recibe onOutbid cuando el segundo puja más.
Buzón, chat y reembolsos
Sección titulada «Buzón, chat y reembolsos»onMailboxClaimed
Sección titulada «onMailboxClaimed»Quién: el jugador. Cuándo: recoge algo de su buzón.
Campos: mailboxId, claimType ('item' o 'money'), amount, item, itemLabel, itemMetadata, quantity, meetupPoint, reason.
Prueba: recoge cualquier cosa de tu buzón (una subasta ganada siempre acaba ahí).
onMessageReceived
Sección titulada «onMessageReceived»Quién: el destinatario. Cuándo: recibe un mensaje en el chat de un anuncio.
| Campo | Significado |
|---|---|
listingId |
Anuncio de la conversación |
conversationKey |
ID de la conversación |
fromIdentifier, partnerIdentifier |
Remitente y la otra parte del chat |
messageId |
ID del mensaje |
messageKind |
Tipo de mensaje |
preview |
Vista previa corta del texto |
Ejemplo: notificación tipo móvil con el marketplace cerrado
AddEventHandler('sl-marketplace:onMessageReceived', function(data) exports['okokNotify']:Alert('Marketplace', data.preview, 4000, 'info')end)Prueba: dos jugadores; B escribe a A desde uno de los anuncios de A.
onRefundStatusChanged
Sección titulada «onRefundStatusChanged»Quién: comprador y vendedor (cada uno con su role). Cuándo: se pide, aprueba, fuerza o rechaza un reembolso.
| Campo | Significado |
|---|---|
refundId, historyId, listingId |
IDs |
role |
'buyer' o 'seller' |
status |
'pending', 'approved', 'forced' o 'rejected' |
item, itemLabel, amount |
Qué y cuánto |
reason / note |
Motivo del comprador o nota del vendedor |
Prueba: dos jugadores; B pide un reembolso de una compra a A, y A lo aprueba o lo rechaza.
Repartidor NPC
Sección titulada «Repartidor NPC»onDeliveryArrived
Sección titulada «onDeliveryArrived»Quién: el comprador. Cuándo: la furgoneta de reparto le entrega el objeto. No se dispara si la furgoneta fue atracada o falló.
Campos: deliveryId, item, itemLabel, quantity, sellerName, listingId, deliveryMode, stage.
Prueba: /markettest listing npc fixed bread 50, cómpralo y espera a la furgoneta.
onDeliveryResult
Sección titulada «onDeliveryResult»Quién: el comprador. Cuándo: termina un reparto, sea cual sea el resultado. Úsalo si quieres un solo handler para todos los casos.
| Campo | Significado |
|---|---|
deliveryId, listingId |
IDs |
result |
'delivered', 'stolen' o 'failed' |
item, itemLabel, quantity, sellerName |
El pedido |
deliveryMode, stage |
Detalles |
reason |
Por qué falló (solo failed) |
refundAmount |
Lo reembolsado, cuando hubo reembolso |
thiefName |
Quién lo atracó (solo stolen) |
Ejemplo
AddEventHandler('sl-marketplace:onDeliveryResult', function(data) if data.result == 'stolen' then exports['okokNotify']:Alert('Reparto', data.thiefName .. ' ha atracado tu paquete', 6000, 'error') endend)Prueba: como onDeliveryArrived para delivered; destruye la furgoneta para failed; haz que otro jugador la atraque para stolen.
onDeliveryRobbed
Sección titulada «onDeliveryRobbed»Quién: el atracador. Cuándo: atraca una furgoneta de reparto (OnDeliveryRobbed).
Campos: deliveryId, item, itemLabel, itemMetadata, quantity, value, trigger ('cargo_stolen' o 'driver_killed'), listingId, stage.
Prueba: dos jugadores; uno compra con entrega por repartidor y el otro atraca la furgoneta.
Intercambios en persona
Sección titulada «Intercambios en persona»onInPersonTradeStarted
Sección titulada «onInPersonTradeStarted»Quién: comprador y vendedor. Cuándo: se crea un intercambio en persona, y otra vez cuando un jugador se reconecta con un intercambio todavía abierto (rehydrated = true).
| Campo | Significado |
|---|---|
tradeId (también id) |
ID del intercambio |
role |
'buyer' o 'seller' |
counterpart, partnerIdentifier |
El otro jugador |
itemLabel, quantity, price, listingId |
El trato |
meetStatus |
Estado del punto de encuentro |
rehydrated |
true cuando se restaura al reconectarse |
Prueba: dos jugadores conectados; B compra uno de los anuncios de A con el modo en persona.
onInPersonMeetUpdated
Sección titulada «onInPersonMeetUpdated»Quién: comprador y vendedor. Cuándo: el punto de encuentro se propone, se acepta, se rechaza, se cancela o caduca.
Campos: tradeId (también id), meetStatus, meetProposedBy, meetProposedCoords, meetProposedAt, meetWindowEndsAt, meetCoords.
Prueba: en un intercambio en persona, propón un lugar desde el chat y acéptalo con el otro jugador.
onInPersonTradeCompleted
Sección titulada «onInPersonTradeCompleted»Quién: comprador y vendedor. Cuándo: los dos confirman el intercambio cara a cara.
Campos: tradeId, role, item (nil en un trueque), itemLabel, quantity (nil en un trueque), price (0 en un trueque), isBarter, tradeKind, barter, platformFee, sellerPayout, listingId, stage.
Prueba: completa un intercambio en persona.
onInPersonTradeCancelled
Sección titulada «onInPersonTradeCancelled»Quién: comprador y vendedor. Cuándo: el intercambio se cancela o se agota su tiempo.
Campos: tradeId (también id), reason, partnerIdentifier.
Prueba: cancela un intercambio en persona desde el chat.
Minijuego de puntería (atraco)
Sección titulada «Minijuego de puntería (atraco)»El anillo que el atracador tiene que acertar para forzar el maletero de una furgoneta. Tres fases, cada una más rápida y con una tecla distinta (se configura en Config.SkillCheck). context es ahora mismo siempre 'deliveryRobbery'.
onSkillCheckStarted
Sección titulada «onSkillCheckStarted»Cuándo: aparece el anillo, antes de la primera fase.
Campos: context, deliveryId, phases (cuántas fases hay).
onSkillCheckPhase
Sección titulada «onSkillCheckPhase»Cuándo: se resuelve cada fase.
| Campo | Significado |
|---|---|
context, deliveryId |
Qué se intenta |
phase |
Fase que se acaba de resolver (1, 2, 3…) |
phases |
Total de fases |
key |
Tecla que pedía la fase ('E', 'Q', 'R', 'F') |
result |
'hit' (acierto) o 'miss' (fallo) |
onSkillCheckFinished
Sección titulada «onSkillCheckFinished»Cuándo: termina el minijuego, acabe como acabe. Siempre después del último onSkillCheckPhase.
| Campo | Significado |
|---|---|
context, deliveryId |
Qué se intentó |
result |
'passed' (todas las fases), 'failed' (falló una fase) o 'cancelled' (se alejó, le dispararon o la furgoneta se fue) |
passed |
true solo con 'passed' |
cleared |
Fases superadas antes de terminar |
phases |
Total de fases |
Ejemplo: tus propios sonidos en lugar de los del script
Pon Config.SkillCheck.Sounds = false y reproduce los tuyos:
AddEventHandler('sl-marketplace:onSkillCheckPhase', function(data) if data.result == 'hit' then PlaySoundFrontend(-1, 'CONFIRM_BEEP', 'HUD_MINI_GAME_SOUNDSET', true) else PlaySoundFrontend(-1, 'ERROR', 'HUD_FRONTEND_DEFAULT_SOUNDSET', true) endend)
AddEventHandler('sl-marketplace:onSkillCheckFinished', function(data) if data.result == 'failed' then -- un intento fallido hace ruido: avisa a la policía desde el SERVIDOR, no desde aquí TriggerServerEvent('your_dispatch:suspicious', 'Ruido en una furgoneta de reparto') endend)Probar los tres: dos jugadores; uno compra con entrega por repartidor y el otro intercepta la furgoneta, amenaza al conductor y empieza a forzar el maletero. Falla una vez a propósito para ver miss y failed.