DRS Community Service
Serviço comunitário para a polícia: formulário do agente, tarefas com animações, castigo por fuga, farda de serviço e HUD. Validado no servidor.
Serviço comunitário para a polícia. O agente escolhe o jogador, o número de tarefas e o motivo; o condenado vai para a zona, veste a farda de serviço e cumpre as tarefas uma a uma — varrer, jardinagem, apanhar lixo e limpar grafítis — com animação e objeto na mão.
#Requisitos
| Framework | QBCore, Qbox, ESX ou nenhum (deteção automática) |
| Base de dados | oxmysql |
#Instalação
- Coloca a pasta
drs_communityserviceemresourcese adiciona aoserver.cfg, depois dooxmysqle do framework:
ensure drs_communityservice- A tabela
drs_community_serviceé criada sozinha. - Ajusta os empregos, a zona, os pontos de tarefa e a farda no
config.lua. - Se tens outro serviço comunitário (ex.:
qb-communityservice), desliga-o.
#Como funciona
- Um polícia em serviço (ou staff) usa
/servicocomunitarioperto do jogador — abre o formulário com a lista dos jogadores perto (distância calculada no servidor). - Escolhe as tarefas (entre
Config.MinTaskseConfig.MaxTasks) e o motivo. - O jogador é levado para
Config.Zone.start, veste a farda e vê um HUD com as tarefas que faltam. - Em cada ponto carrega em E: animação, objeto na mão e barra de progresso. Afastar-se cancela.
- Ao acabar é levado para
Config.Zone.releasee a roupa original volta.
Atenção
Sair do raio da zona conta como fuga: o jogador volta para dentro e leva Config.EscapePenalty tarefas extra. Sair do servidor não livra ninguém — o que falta fica guardado.
#Comandos
| Comando | Quem | O que faz |
|---|---|---|
/servicocomunitario | polícia / staff | Abre o formulário |
/servicocomunitario [id] [tarefas] [motivo] | polícia / staff / consola | Aplica sem formulário |
/libertarservico [id] | polícia / staff / consola | Liberta o jogador |
/servico | todos | Mostra quantas tarefas faltam |
O staff é reconhecido pelos grupos em Config.StaffGroups ou pela ACE drs.communityservice.
#Tipos de tarefa
Cada tipo tem tempo, animação (ou scenario), objeto e cor do marcador. Acrescentar um tipo é só uma entrada nova:
sweep = {
label = 'Varrer o chão', time = 8,
anim = { dict = 'amb@world_human_janitor@male@base', clip = 'base' },
prop = { model = 'prop_tool_broom', bone = 28422, pos = vector3(-0.01, 0.04, -0.03), rot = vector3(0.0, 0.0, 0.0) },
marker = { r = 96, g = 165, b = 250 },
},E os pontos, dentro da zona: { type = 'sweep', coords = vector3(...) }.
#Opções principais
| Opção | Por defeito | Descrição |
|---|---|---|
Config.Jobs | police, sheriff | Empregos que aplicam |
Config.RequireDuty | true | Tem de estar em serviço |
Config.MaxDistance | 10.0 | Distância máxima entre o agente e o jogador |
Config.MinTasks / Config.MaxTasks | 5 / 150 | Limites por sentença |
Config.Zone | Legion Square | Centro, raio, entrada e saída |
Config.EscapePenalty | 5 | Tarefas extra por fuga |
Config.DisarmDuringService | true | Sem armas nem veículos |
Config.Outfit | homem/mulher | Farda de serviço (vazio = não muda) |
#Configuração completa
Config = {}
-- Idioma / Language: 'pt' ou 'en'
Config.Locale = 'pt'
-- Framework: 'auto' deteta Qbox/QBCore/ESX (ou 'qbx' | 'qb' | 'esx' | 'none')
Config.Framework = 'auto'
-- ------------------------------------------------------------------ quem aplica / who can sentence
-- Empregos que podem mandar para serviço comunitário / Jobs that can sentence
Config.Jobs = { 'police', 'sheriff' }
-- Cargo mínimo (0 = qualquer) e se é preciso estar em serviço / Minimum grade (0 = any) and on-duty requirement
Config.MinGrade = 0
Config.RequireDuty = true
-- O staff (ACE drs.communityservice ou grupo admin) também pode / Staff can too
Config.StaffCanSentence = true
Config.StaffGroups = { 'god', 'admin', 'superadmin' }
-- Distância máxima entre o agente e o jogador (0 = sem limite) / Max distance officer → player (0 = no limit)
Config.MaxDistance = 10.0
-- Comandos / Commands
Config.Command = 'servicocomunitario' -- abre o formulário (ou: /servicocomunitario [id] [tarefas] [motivo])
Config.ReleaseCommand = 'libertarservico' -- /libertarservico [id]
Config.CheckCommand = 'servico' -- o jogador vê quantas tarefas faltam / player checks remaining tasks
-- Limites de tarefas por sentença / Task limits per sentence
Config.MinTasks = 5
Config.MaxTasks = 150
-- ------------------------------------------------------------------ zona / zone
Config.Zone = {
center = vector3(185.0, -1003.0, 29.3),
radius = 45.0, -- sair daqui conta como fuga / leaving counts as escaping
start = vector4(170.4, -994.9, 30.1, 160.0), -- onde o jogador aparece / where the player appears
release = vector4(133.1, -990.0, 29.5, 250.0),-- onde é solto no fim / where they are released
blip = { sprite = 566, color = 5, scale = 0.8 },
}
-- Tarefas extra por cada fuga / Extra tasks for each escape
Config.EscapePenalty = 5
-- Tirar as armas durante o serviço (voltam no fim) / Hold weapons during service (given back at the end)
-- Só desarma na mão; o inventário não é tocado / Only unequips; the inventory is not touched
Config.DisarmDuringService = true
-- ------------------------------------------------------------------ tipos de tarefa / task types
-- time: segundos que a tarefa demora (o servidor valida) / seconds the task takes (server-checked)
-- anim: animação (dict/clip) ou scenario; prop: objeto na mão
Config.TaskTypes = {
sweep = {
label = 'Varrer o chão', time = 8,
anim = { dict = 'amb@world_human_janitor@male@base', clip = 'base' },
prop = { model = 'prop_tool_broom', bone = 28422, pos = vector3(-0.01, 0.04, -0.03), rot = vector3(0.0, 0.0, 0.0) },
marker = { r = 96, g = 165, b = 250 },
},
garden = {
label = 'Tratar do jardim', time = 10,
scenario = 'WORLD_HUMAN_GARDENER_PLANT',
marker = { r = 74, g = 222, b = 128 },
},
trash = {
label = 'Apanhar lixo', time = 6,
anim = { dict = 'anim@amb@drug_field_workers@rake@male_a@base', clip = 'base' },
prop = { model = 'prop_cs_rub_binbag_01', bone = 57005, pos = vector3(0.12, 0.0, -0.05), rot = vector3(10.0, 0.0, 0.0) },
marker = { r = 251, g = 191, b = 36 },
},
graffiti = {
label = 'Limpar grafíti', time = 9,
scenario = 'WORLD_HUMAN_MAID_CLEAN',
marker = { r = 192, g = 132, b = 252 },
},
}
-- Pontos de tarefa (dentro da zona) / Task spots (inside the zone)
Config.Spots = {
{ type = 'sweep', coords = vector3(170.0, -1006.0, 29.34) },
{ type = 'sweep', coords = vector3(177.0, -1007.9, 29.33) },
{ type = 'sweep', coords = vector3(181.6, -1009.5, 29.34) },
{ type = 'sweep', coords = vector3(189.3, -1009.5, 29.34) },
{ type = 'sweep', coords = vector3(195.3, -1016.0, 29.34) },
{ type = 'trash', coords = vector3(169.9, -1001.3, 29.34) },
{ type = 'trash', coords = vector3(164.7, -1008.0, 29.43) },
{ type = 'trash', coords = vector3(163.3, -1000.6, 29.35) },
{ type = 'garden', coords = vector3(181.4, -1000.1, 29.29) },
{ type = 'garden', coords = vector3(188.4, -1000.4, 29.29) },
{ type = 'garden', coords = vector3(194.8, -1002.0, 29.29) },
{ type = 'garden', coords = vector3(199.0, -1006.9, 29.29) },
{ type = 'graffiti', coords = vector3(201.5, -1004.4, 29.29) },
}
-- ------------------------------------------------------------------ roupa / clothing
-- Roupa durante o serviço (freemode). Vazio = não muda. A roupa original volta no fim.
-- Clothing during service (freemode). Empty = unchanged. The original clothes come back at the end.
-- [componente] = { drawable, texture }
Config.Outfit = {
male = {
[3] = { 0, 0 }, [4] = { 36, 0 }, [6] = { 25, 0 }, [8] = { 59, 0 }, [11] = { 56, 0 },
},
female = {
[3] = { 14, 0 }, [4] = { 35, 0 }, [6] = { 26, 0 }, [8] = { 36, 0 }, [11] = { 49, 0 },
},
}
-- ------------------------------------------------------------------ interface / UI
Config.InteractKey = 38 -- E
Config.InteractKeyLabel = 'E'
Config.HudPosition = 'right-center' -- 'right-center' | 'left-center' | 'top-center'
-- Webhook do Discord (vazio = desligado) / Discord webhook (empty = off)
Config.Webhook = ''
-- Notificações com ox_lib quando estiver a correr / Use ox_lib notifications when it is running
Config.UseOxNotify = false#Para programadores
exports.drs_communityservice:Sentence(target, 10, 'Condução perigosa', officerSrc) -- officer 0 = sem verificação
exports.drs_communityservice:Release(target)
exports.drs_communityservice:IsServing(src)
exports.drs_communityservice:GetRemaining(src)O statebag communityService (true/false) está no jogador — Player(src).state.communityService.
#Resolução de problemas
"Não tens permissão para isto." — o agente não tem o emprego de Config.Jobs, não está em serviço ou tem cargo abaixo de Config.MinGrade.
"O jogador está demasiado longe." — aproxima-te (limite em Config.MaxDistance; 0 desliga).
A tarefa não conta — o jogador afastou-se do ponto ou a tarefa não durou o tempo todo; o servidor recusa.