Eventos do servidor
Eventos são a forma de reagir ao que acontece no servidor: um jogador entra, um veículo explode, alguém pega um pickup. Você registra uma função e o servidor a chama quando aquilo acontece.
addEventHandler("onPlayerJoin", root, function() outputDebugString(getPlayerName(source) .. " entrou no servidor")end)Todos os manipuladores registrados por um resource são removidos quando ele para.
addEventHandler
Seção intitulada “addEventHandler”Registra uma função para ser chamada quando o evento disparar.
bool addEventHandler ( string nomeDoEvento, element elemento, function manipulador [, bool propagar = true, string prioridade = "normal" ] )Parâmetros
| Nome | Tipo | Descrição |
|---|---|---|
nomeDoEvento | string | Nome do evento. |
elemento | element | Elemento ao qual o manipulador fica preso. Veja Propagação. |
manipulador | function | Função a chamar. Recebe os parâmetros do evento como argumentos. |
propagar | bool | false faz o manipulador rodar só quando elemento é o próprio source. O padrão é true. |
prioridade | string | "low", "normal" (o padrão) ou "high", opcionalmente com um modificador como "high+5". Decide a ordem entre manipuladores no mesmo ponto da árvore. |
Retorno — true se o manipulador foi registrado, false caso contrário.
Um erro dentro do manipulador não derruba o servidor nem impede os outros manipuladores de rodar: ele é registrado no console com o nome do resource e do evento.
removeEventHandler
Seção intitulada “removeEventHandler”Desfaz um addEventHandler.
bool removeEventHandler ( string nomeDoEvento, element elemento, function manipulador )O nome, o elemento e a função precisam ser exatamente os mesmos usados no registro — por isso guarde a função em uma variável se pretende removê-la depois.
local function aoEntrar() outputDebugString(getPlayerName(source) .. " entrou")end
addEventHandler("onPlayerJoin", root, aoEntrar)removeEventHandler("onPlayerJoin", root, aoEntrar)Retorno — true se o manipulador existia e foi removido, false caso contrário.
getEventHandlers
Seção intitulada “getEventHandlers”Lista os manipuladores presos diretamente a um elemento.
table getEventHandlers ( string nomeDoEvento, element elemento )Só aparecem os manipuladores registrados pelo seu próprio resource — os de outros resources ficam invisíveis. Um elemento sem manipuladores devolve uma tabela vazia; um argumento inválido devolve false.
for _, fn in ipairs(getEventHandlers("onPlayerJoin", root)) do removeEventHandler("onPlayerJoin", root, fn)endGlobais do manipulador
Seção intitulada “Globais do manipulador”Enquanto um manipulador está executando, cinco globais ficam disponíveis:
| Global | Conteúdo |
|---|---|
source | O elemento que originou o evento — o mesmo descrito na linha Source de cada evento abaixo. |
client | O jogador que enviou o evento, quando ele veio do cliente. É nil em eventos disparados pelo próprio servidor. |
eventName | O nome do evento em execução, como texto. |
sourceResource | O resource cujo script chamou triggerEvent. É nil quando quem disparou foi a engine ou a rede. |
sourceResourceRoot | O elemento raiz desse resource, nil nos mesmos casos. |
Cada manipulador recebe o próprio conjunto de valores e tem eles restaurados ao retornar, então um manipulador que dispara um evento aninhado continua vendo o seu próprio source na linha seguinte à chamada aninhada.
addEventHandler("onVehicleExplode", root, function(comExplosao) local veiculo = source -- cópia local: sobrevive ao timer outputDebugString(eventName .. " em " .. getVehicleName(veiculo))
setTimer(function() if isElement(veiculo) then respawnVehicle(veiculo) end end, 5000, 1)end)Os parâmetros do evento não são globais: eles chegam como argumentos normais da função, na ordem descrita na referência abaixo.
Propagação
Seção intitulada “Propagação”O elemento passado ao addEventHandler não precisa ser exatamente o source do evento. O manipulador roda quando qualquer uma destas condições é verdadeira:
- o elemento é o próprio
source; - o
sourceé descendente do elemento, em qualquer profundidade; - o elemento é a raiz (
root); - o elemento é descendente do
source— os eventos descem pela árvore, além de subir.
Ou seja: prender à raiz pega tudo, prender à raiz do seu resource pega tudo o que o seu resource criou, e prender a um elemento específico pega ele e os filhos dele — além de qualquer evento disparado num ancestral dele, como um triggerEvent no root.
Os manipuladores rodam nessa ordem: os do source, depois os dos ancestrais, do mais próximo para cima, depois os dos descendentes. No mesmo ponto da árvore, quem decide é a prioridade. Um manipulador registrado com propagar igual a false só roda quando está preso ao próprio source.
local garagem = createElement("garagem")local carro = createVehicle(411, 0, 0, 5)setElementParent(carro, garagem)
-- roda para qualquer veículo do servidoraddEventHandler("onVehicleExplode", root, function() end)
-- roda só para os veículos dentro da "garagem"addEventHandler("onVehicleExplode", garagem, function() end)
-- roda só para este carroaddEventHandler("onVehicleExplode", carro, function() end)Quando um evento é disparado sem elemento de origem, apenas os manipuladores presos à raiz são executados.
Eventos personalizados
Seção intitulada “Eventos personalizados”Além dos eventos do servidor, você pode criar os seus.
addEvent
Seção intitulada “addEvent”Registra um nome de evento.
bool addEvent ( string nomeDoEvento [, bool permitirRemoto = false ] )| Nome | Tipo | Padrão | Descrição |
|---|---|---|---|
nomeDoEvento | string | — | Nome do evento. |
permitirRemoto | bool | false | Se true, scripts do cliente podem disparar este evento no servidor. |
triggerEvent
Seção intitulada “triggerEvent”Dispara um evento no servidor, agora, no mesmo tick.
bool triggerEvent ( string nomeDoEvento, element origem [, ... ] )Os valores extras viram os argumentos do manipulador.
Retorno — false se algum manipulador cancelou o evento, true caso contrário (inclusive quando ninguém está escutando).
addEvent("onCompraDeArma")
addEventHandler("onCompraDeArma", root, function(arma, preco) if getElementData(source, "dinheiro") < preco then cancelEvent(true, "saldo insuficiente") endend)
addEventHandler("onCompraDeArma", root, function() if wasEventCancelled() then outputDebugString("compra recusada: " .. getCancelReason()) endend, true, "low") -- roda depois do manipulador acima
if triggerEvent("onCompraDeArma", jogador, 31, 5000) then giveWeapon(jogador, 31, 200)endtriggerClientEvent
Seção intitulada “triggerClientEvent”Dispara um evento nos clientes.
bool triggerClientEvent ( element/table destinos, string nomeDoEvento, element origem [, ... ] )| Nome | Tipo | Descrição |
|---|---|---|
destinos | element ou table | Para quem enviar. Um jogador atinge só ele; qualquer outro elemento atinge todos os jogadores abaixo dele na árvore — passar root atinge o servidor inteiro. Uma tabela de elementos também é aceita. |
nomeDoEvento | string | Nome do evento no cliente. |
origem | element | Elemento que vira o source do lado do cliente. |
... | any | Argumentos repassados ao manipulador do cliente. |
Do lado do cliente, o evento só é entregue se tiver sido registrado com addEvent(nome, true). Sem isso, a mensagem é descartada silenciosamente.
triggerClientEvent(root, "onPlacarAtualizado", root, "Gabriel", 12)Para uma carga grande, triggerLatentClientEvent manda o mesmo evento por uma fila com banda limitada, em vez de tudo de uma vez.
Cancelando eventos
Seção intitulada “Cancelando eventos”cancelEvent
Seção intitulada “cancelEvent”Marca o evento em execução como cancelado.
bool cancelEvent ( [ bool cancelar = true, string motivo = "" ] )Sempre devolve true. Chamar cancelEvent(false) não faz nada — em particular, não desfaz um cancelamento feito por outro manipulador.
wasEventCancelled
Seção intitulada “wasEventCancelled”bool wasEventCancelled ( )Devolve true se o evento em execução já foi cancelado por algum manipulador.
getCancelReason
Seção intitulada “getCancelReason”string getCancelReason ( )Devolve o motivo passado ao cancelEvent para o evento em execução, ou uma string vazia se não houve motivo. Depois que triggerEvent retorna, o motivo some — leia-o num manipulador posterior, como no exemplo acima.
Referência de eventos
Seção intitulada “Referência de eventos”O servidor dispara 86 eventos, agrupados por área:
Jogadores
Seção intitulada “Jogadores”Combate
Seção intitulada “Combate”Os eventos de combate nascem do relato do cliente. O servidor valida cada número antes de disparar o evento — dano fora da faixa de 0 a 200, atacante em outra dimensão ou interior, morte relatada duas vezes e faca a mais de 5 unidades de distância são descartados sem disparar nada.
Veículos
Seção intitulada “Veículos”Objetos
Seção intitulada “Objetos”Fratura
Seção intitulada “Fratura”Elementos
Seção intitulada “Elementos”Formas de colisão
Seção intitulada “Formas de colisão”Cada entrada e cada saída disparam um par de eventos: um com a forma como source e outro com o elemento como source. A verificação roda para jogadores, peds, veículos e objetos.
Marcadores
Seção intitulada “Marcadores”Marcadores funcionam como as formas de colisão, com duas diferenças: o interior precisa bater (um elemento em outro interior conta como fora do marcador) e existe um par extra de eventos só para jogadores.
O formato depende do tipo do marcador: checkpoint e cylinder ignoram a altura, e todos os demais são esferas. O raio é o tamanho do marcador.
Pickups
Seção intitulada “Pickups”Cada coleta dispara um par de eventos: um com o pickup como source e outro com o jogador como source. Os dois sempre disparam; cancelar qualquer um dos dois já é suficiente para bloquear o efeito.
Um pickup só é testado contra jogadores vivos, no mesmo interior e na mesma dimensão, dentro de um raio de 1 unidade.
Resources
Seção intitulada “Resources”Comandos e moderação
Seção intitulada “Comandos e moderação”Estes eventos só existem quando o chat de voz está ligado na configuração do servidor.