ps-dispatch — Manual

Sistema de despacho para polícia e EMS: alertas com blips, sons, lista de chamadas em NUI e mais de 30 exports prontos para outros recursos dispararem ocorrências.


Sumário

  1. Dependências
  2. Instalação
  3. Configuração
  4. Comandos
  5. Teclas
  6. Alertas automáticos
  7. Zonas
  8. Blips e sons
  9. Integrações
  10. Entrypoints para outros recursos
  11. Localização
  12. Estrutura de arquivos

Dependências

RecursoObrigatórioObservação
qbx_coreSimFramework base. O recurso usa exports['qb-core']:GetCoreObject(), resolvido pelo provide 'qb-core' do qbx_core
ox_libSimLocale, callbacks, keybinds, zonas (lib.zones) e comandos (lib.addCommand). v3.8.0 ou superior
PolyZoneSimDeclarado no fxmanifest.lua (@PolyZone/client.lua, CircleZone, BoxZone)
interact-soundNãoNecessário apenas para os sons dispatch, panicbutton e robberysound. Sem ele, os alertas que usam esses sons ficam mudos

Instalação

  1. Copie a pasta ps-dispatch para resources/.
  2. Adicione ao server.cfg:
    ensure ps-dispatch
  3. Copie os arquivos de sounds/ (dispatch.ogg, panicbutton.ogg, robberysound.ogg) para interact-sound/client/html/sounds/. Sem isso, os alertas de socorro (officerdown, officerbackup, emsdown) e os de assalto não tocam som.
  4. Conflitos — não rode junto com outro recurso de dispatch (qb-dispatch, cd_dispatch, etc.). Os comandos /911 e /311 e o evento ps-dispatch:server:notify colidem.

Configuração

Arquivo: shared/config.lua.

CampoTipoObrigatórioDescrição
Config.ShortCallsboolSimQuando true, a notificação mostra só o nome do alerta; os detalhes ficam apenas no menu de dispatch
Config.DebugboolSimAtiva o debug das zonas e faz jogadores com job type leo também gerarem alertas de tiro e de excesso de velocidade
Config.RespondKeybindstringSimTecla padrão para marcar waypoint no último chamado (padrão Y)
Config.OpenDispatchMenustringSimTecla padrão para abrir o menu de dispatch (padrão F2)
Config.AlertTimenúmero (s)SimTempo que o alerta fica na tela quando o alerta não define alertTime próprio
Config.MaxCallListnúmeroSimMáximo de chamados guardados no servidor; ao estourar, o mais antigo é descartado
Config.OnDutyOnlyboolSimQuando true, só quem está em serviço (job.onduty) recebe alertas
Config.Jobsarray de stringsSimJob types que podem abrir o menu de dispatch (padrão: leo, ems)
Config.DefaultAlertsDelaynúmero (s)SimCooldown entre alertas automáticos do mesmo tipo, evita spam
Config.DefaultAlertstabela de boolSimLiga/desliga cada alerta automático: Speeding, Shooting, Autotheft, Melee, PlayerDowned, Explosion
Config.MinOffsetnúmeroSimOffset mínimo de deslocamento do blip
Config.MaxOffsetnúmeroSimOffset máximo (em metros) aplicado a blips com offset = true
Config.PhoneRequiredboolSimQuando true, exige um item de telefone no inventário para usar /911 e /311
Config.PhoneItemsarray de stringsSimNomes dos itens aceitos como telefone (padrão: phone)
Config.EnableHuntingBlipboolSimDesenha um blip permanente nas zonas de caça
Config.Locations.HuntingZonesarraySimEsferas onde tiros geram alerta de caça em vez de tiroteio. Campos: label, radius, coords
Config.Locations.NoDispatchZonesarraySimCaixas onde tiros não geram alerta nenhum. Campos: label, coords, length, width, heading, minZ, maxZ
Config.WeaponWhitelistarray de stringsSimArmas que não disparam alerta de tiro (granadas, taser, extintor, etc.)
Config.BlipstabelaSimAparência do blip e som por codeName de alerta — veja Blips e sons
Config.ColorstabelaSimMapa de índice de cor do GTA para nome legível, usado na descrição do veículo no chamado

Comandos

Todos registrados via lib.addCommand. Não há restrição por ACE — o filtro é o job do jogador.

ComandoPermissãoDescrição
/dispatchJob type em Config.JobsAbre o menu de chamados
/911 [mensagem]Qualquer jogadorEnvia chamado para a polícia (job type leo)
/911a [mensagem]Qualquer jogadorIgual ao /911, mas anônimo (nome e número ocultos)
/311 [mensagem]Qualquer jogadorEnvia chamado para o EMS (job type ems)
/311a [mensagem]Qualquer jogadorIgual ao /311, mas anônimo

As chamadas /911 e /311 só passam se a mensagem não estiver vazia, o jogador não estiver algemado (metadata.ishandcuffed) e — quando Config.PhoneRequired está ligado — houver um item de Config.PhoneItems no inventário.


Teclas

Registradas via lib.addKeybind; o jogador pode reatribuí-las em Configurações > Teclas do FiveM.

NomePadrãoAção
mri_Q:RespondToDispatchConfig.RespondKeybind (Y)Marca waypoint no último chamado e anexa o jogador como unidade. Só fica ativa enquanto o alerta está na tela
mri_Q:OpenDispatchMenuConfig.OpenDispatchMenu (F2)Abre o menu de chamados

Alertas automáticos

O client/eventhandlers.lua escuta eventos nativos do jogo e dispara alertas sozinho. Cada um respeita a flag correspondente em Config.DefaultAlerts e o cooldown de Config.DefaultAlertsDelay.

FlagGatilhoAlerta gerado
ShootingCEventGunShotVehicleShooting se estiver em veículo, Hunting se estiver em zona de caça, senão Shooting. Ignora arma silenciada, arma na whitelist e zona sem dispatch
MeleeCEventShockingSeenMeleeActionFight
AutotheftCEventPedJackingMyVehicleCarJacking
AutotheftCEventShockingCarAlarmVehicleTheft
ExplosionCEventExplosionHeardExplosion
PlayerDownedCEventNetworkEntityDamage (morte)OfficerDown se o job type for leo, EmsDown se for ems, senão InjuriedPerson
SpeedingEventos de direção perigosa (CEventShockingCarChase e afins)SpeedingVehicle, apenas acima de ~80–100 km/h e como condutor

Jogadores com job type leo não geram alertas de tiro nem de excesso de velocidade, a menos que Config.Debug esteja ligado.


Zonas

Definidas em Config.Locations e criadas com lib.zones na inicialização do recurso.

  • HuntingZones — esferas (coords + radius). Tiros dentro delas viram alerta Hunting em vez de Shooting. O blip permanente só aparece se Config.EnableHuntingBlip = true.
  • NoDispatchZones — caixas (coords, length, width, heading, minZ, maxZ). Tiros dentro delas não geram alerta algum. As duas Ammunation já vêm configuradas.

Blips e sons

Config.Blips é indexado pelo codeName do alerta (shooting, carjack, bankrobbery, officerdown, …). Cada entrada aceita:

CampoTipoDescrição
radiusnúmeroRaio do blip circular ao redor da ocorrência (0 = sem raio)
spritenúmeroSprite do blip
colornúmeroCor do blip
scalenúmeroEscala do blip
lengthnúmero (min)Quanto tempo o blip leva para sumir (o raio some por fade)
soundstringSom tocado. Lose_1st usa o PlaySound nativo; qualquer outro valor é enviado ao interact-sound
sound2stringSoundset do som nativo (ex.: GTAO_FM_Events_Soundset)
offsetboolQuando true, o blip é deslocado aleatoriamente em até Config.MaxOffset metros
flashboolFaz o blip piscar

Um codeName sem entrada em Config.Blips cai no bloco alert embutido no próprio alerta — é o caminho usado pelo CustomAlert.


Integrações

interact-sound

Os sons dispatch, panicbutton e robberysound são tocados via TriggerServerEvent("InteractSound_SV:PlayOnSource", som, 0.25). Os arquivos .ogg estão em sounds/ e precisam ser copiados para o interact-sound. Alertas cujo som é Lose_1st usam o PlaySound nativo e não dependem desse recurso.

Recursos de heist e crime

Qualquer recurso dispara uma ocorrência chamando os exports de alerta no lado cliente. Os alertas de assalto (FleecaBankRobbery, PaletoBankRobbery, PacificBankRobbery, VangelicoRobbery, StoreRobbery) aceitam um camId opcional, exibido no chamado como identificação da câmera de segurança.


Entrypoints para outros recursos

Alertas prontos (cliente)

Todos coletam sozinhos coordenadas, rua, direção e dados do veículo do jogador que chamou.

-- Genéricos
exports['ps-dispatch']:Shooting()
exports['ps-dispatch']:VehicleShooting()
exports['ps-dispatch']:SpeedingVehicle()
exports['ps-dispatch']:Fight()
exports['ps-dispatch']:Hunting()
exports['ps-dispatch']:Explosion()
exports['ps-dispatch']:SuspiciousActivity()
exports['ps-dispatch']:DrugDealing()
exports['ps-dispatch']:DrugSale()
 
-- Veículos
exports['ps-dispatch']:VehicleTheft()          -- usa o veículo atual do jogador
exports['ps-dispatch']:CarJacking(vehicle)     -- entity do veículo
exports['ps-dispatch']:CarBoosting(vehicle)    -- entity do veículo
 
-- Assaltos (camId é opcional e aparece no chamado)
exports['ps-dispatch']:StoreRobbery(camId)
exports['ps-dispatch']:FleecaBankRobbery(camId)
exports['ps-dispatch']:PaletoBankRobbery(camId)
exports['ps-dispatch']:PacificBankRobbery(camId)
exports['ps-dispatch']:VangelicoRobbery(camId)
exports['ps-dispatch']:HouseRobbery()
exports['ps-dispatch']:YachtHeist()
exports['ps-dispatch']:PrisonBreak()
exports['ps-dispatch']:SignRobbery()
exports['ps-dispatch']:ArtGalleryRobbery()
exports['ps-dispatch']:HumaneRobbery()
exports['ps-dispatch']:TrainRobbery()
exports['ps-dispatch']:VanRobbery()
exports['ps-dispatch']:UndergroundRobbery()
exports['ps-dispatch']:DrugBoatRobbery()
exports['ps-dispatch']:UnionRobbery()
 
-- Socorro
exports['ps-dispatch']:OfficerDown()
exports['ps-dispatch']:OfficerBackup()
exports['ps-dispatch']:OfficerInDistress()
exports['ps-dispatch']:EmsDown()
exports['ps-dispatch']:InjuriedPerson()
exports['ps-dispatch']:DeceasedPerson()

Alerta customizado (cliente)

exports['ps-dispatch']:CustomAlert({
    message = 'Atividade suspeita',   -- título do alerta
    dispatchCode = 'meualerta',       -- vira o codeName; use para casar com Config.Blips
    code = '10-80',                   -- código exibido antes do título
    icon = 'fas fa-question',         -- ícone Font Awesome
    priority = 2,                     -- 1 = vermelho, 2 = padrão
    coords = GetEntityCoords(cache.ped),
    job = { 'leo' },                  -- lista de recipients
    gender = true,                    -- inclui o gênero do jogador no chamado
    alertTime = 10,                   -- segundos na tela (nil = Config.AlertTime)
    -- blip usado quando o dispatchCode não existe em Config.Blips
    radius = 0, sprite = 1, color = 1, scale = 0.5, length = 2,
    sound = 'Lose_1st', sound2 = 'GTAO_FM_Events_Soundset',
    offset = false, flash = false,
})

Servidor

-- Lista de chamados ativos
local calls = exports['ps-dispatch']:GetDispatchCalls()
 
-- Enviar um alerta já montado a partir do servidor
TriggerEvent('ps-dispatch:server:notify', dispatchData)

Eventos de rede

-- Cliente -> servidor
TriggerServerEvent('ps-dispatch:server:notify', dispatchData)
TriggerServerEvent('ps-dispatch:server:attach', callId, playerData)  -- anexa unidade ao chamado
TriggerServerEvent('ps-dispatch:server:detach', callId, playerData)  -- desanexa unidade
 
-- Servidor -> cliente
TriggerClientEvent('ps-dispatch:client:openMenu', src, calls)
TriggerClientEvent('ps-dispatch:client:sendEmergencyMsg', src, mensagem, '911', anonimo)
TriggerClientEvent('ps-dispatch:client:officerdown', src)
TriggerClientEvent('ps-dispatch:client:officerbackup', src)
TriggerClientEvent('ps-dispatch:client:emsdown', src)

Callbacks (lib.callback)

local calls  = lib.callback.await('ps-dispatch:callback:getCalls', false)
local latest = lib.callback.await('ps-dispatch:callback:getLatestDispatch', false)

Localização

As strings são traduzidas via ox_lib locale. Arquivos em locales/:

  • cs.json, de.json, en.json, es.json, fr.json, nl.json, pt-br.json

O idioma ativo vem da convar no server.cfg:

setr ox:locale "pt-br"

Para adicionar um idioma, crie locales/<codigo>.json seguindo a estrutura do en.json e reinicie o recurso.


Estrutura de arquivos

ps-dispatch/
├── client/
│   ├── main.lua           — NUI, menu, blips, keybinds, zonas e callbacks NUI
│   ├── alerts.lua         — todos os exports de alerta e o CustomAlert
│   ├── eventhandlers.lua  — alertas automáticos a partir de eventos do jogo
│   └── utils.lua          — dados do veículo, rua/zona, gênero, direção, checagem de telefone
├── server/
│   └── main.lua           — lista de chamados, attach/detach de unidades, comandos e callbacks
├── shared/
│   └── config.lua         — todas as opções, blips por alerta e tabela de cores
├── html/                  — build da UI (index.html, index.js, index.css)
├── ui/                    — código-fonte Svelte da UI (não é carregado em runtime)
├── sounds/                — dispatch.ogg, panicbutton.ogg, robberysound.ogg (copiar para o interact-sound)
├── locales/               — cs, de, en, es, fr, nl, pt-br
└── fxmanifest.lua