Início › Documentação › Personalização · origen_parking
A pasta custom/ permite-te integrar qualquer framework, sistema de chaves ou sistema de combustível sem mexer no núcleo. Todos os ficheiros aqui presentes sobrevivem às atualizações.
custom/
├── sv_framework.lua — server-side: identifier, permissions, money, notifications, garages
├── sv_keys.lua — server-side: give keys, set lock state
├── cl_framework.lua — client-side: identifier, notifications, player loaded event
├── cl_keys.lua — client-side: read lock state
└── cl_fuel.lua — client-side: get/set fuel levelFramework.GetIdentifier(source) → string | nilDevolve o identificador único de um jogador (citizenid / license). É chamado em cada ação de estacionar ou recuperar.
function Framework.GetIdentifier(source)
-- Config.Framework == 'custom'
return nil -- replace with your own logic
endFramework.GetVehicleOwner(plate) → string | nilDevolve o identificador do proprietário de uma matrícula a partir da tabela de veículos da framework.
function Framework.GetVehicleOwner(plate)
-- Config.Framework == 'custom'
return nil
endFramework.SetVehicleStorageState(plate, stored)Marca um veículo como guardado (stored = true) ou fora (stored = false) na tabela de veículos da framework.
function Framework.SetVehicleStorageState(plate, stored)
-- Config.Framework == 'custom'
endFramework.HasAdminPermission(source, permission) → booleanÉ chamado em todos os callbacks de administração. Os sistemas de permissões são verificados por esta ordem:
origen_admin — exports['origen_admin']:HasPermission(src, permission)ace — IsPlayerAceAllowed(src, Config.AdminAceNode)qbx / qb — verifica PlayerData.group para god, superadmin, adminesx — verifica xPlayer.getGroup() para superadmin, admincustom — implementa abaixofunction Framework.HasAdminPermission(source, permission)
-- Config.AdminSystem == 'custom'
return false
endFramework.Notify(source, message, ntype)Envia uma notificação a um jogador. ntype: 'info' | 'success' | 'error'
function Framework.Notify(source, message, ntype)
-- Config.NotifySystem == 'custom'
endFramework.GetGarages() → table[]Devolve uma lista de garagens para o painel de administração. Cada entrada: { id, name, label }.
function Framework.GetGarages()
-- Config.GarageIntegration == 'custom'
return {}
endFramework.GetMoney(source) → numberDevolve o saldo em dinheiro de um jogador. É usado pelo sistema de custo de estacionamento.
function Framework.GetMoney(source)
-- Config.Framework == 'custom'
return 0
endFramework.RemoveMoney(source, amount) → booleanDesconta dinheiro a um jogador. Devolve true em caso de sucesso.
function Framework.RemoveMoney(source, amount)
-- Config.Framework == 'custom'
return false
endFramework.GetVehicleState(plate) → number | nilDevolve o estado de armazenamento de um veículo segundo a tabela da framework (1 = fora, 0 = guardado, ou nil se não for encontrado).
function Framework.GetVehicleState(plate)
-- Config.Framework == 'custom'
return nil
endO sistema de estacionamento comunica com o teu sistema de chaves através de dois ficheiros ponte: custom/sv_keys.lua (dar chaves e definir o bloqueio) e custom/cl_keys.lua (ler o estado do bloqueio). O caminho que corre depende de Config.KeySystem:
Config.KeySystem |
Comportamento |
|---|---|
qbx_vehiclekeys |
GiveKeys + SetLockState através dos exports do qbx, com alternativa nativa. |
qb-vehiclekeys |
GiveKeys através do export do qb, bloqueio aplicado com o nativo + state bag. |
qs-vehiclekeys |
GiveKeys + setLocked através dos exports do qs, com alternativa nativa. |
rk-keys |
addKey através do export do rk, bloqueio nativo. |
none |
Não são dadas chaves, os veículos aparecem desbloqueados. |
custom |
Implementas a ponte em sv_keys.lua / cl_keys.lua. |
Seja qual for o Config.KeySystem, a forma recomendada de controlar o estacionar/desestacionar a partir do teu sistema de chaves são os hooks de cliente explícitos abaixo. São determinísticos e executam todas as verificações de elegibilidade, sem adivinhar nada.
Chama estes exports de cliente a partir do teu sistema de chaves sempre que o jogador bloquear ou desbloquear um veículo. O sistema de estacionamento trata do resto (verificações de elegibilidade, estacionar/desestacionar no servidor). Ambos aceitam um handle de entidade do veículo e não fazem nada se o veículo não for elegível.
exports['origen_parking']:onVehicleLocked(vehicle) -- park this vehicle
exports['origen_parking']:onVehicleUnlocked(vehicle) -- unpark this vehicleLigação a partir de um evento de bloqueio/desbloqueio (a maioria dos sistemas de chaves de qb / esx dispara um):
AddEventHandler('my_keys:client:vehicleLocked', function(veh)
exports['origen_parking']:onVehicleLocked(veh)
end)
AddEventHandler('my_keys:client:vehicleUnlocked', function(veh)
exports['origen_parking']:onVehicleUnlocked(veh)
end)Ligação a partir do state bag do bloqueio das portas (qbx_vehiclekeys e semelhantes publicam doorslockstate):
AddStateBagChangeHandler('doorslockstate', nil, function(bagName, _, value)
local veh = GetEntityFromStateBagName(bagName)
if veh == 0 then return end
if value and value >= 2 then
exports['origen_parking']:onVehicleLocked(veh)
else
exports['origen_parking']:onVehicleUnlocked(veh)
end
end)Os sistemas de chaves que só usam nativos bloqueiam o carro no servidor, pelo que o cliente dono da entidade nem sempre consegue observar o bloqueio através da verificação nativa periódica. Para esses sistemas, os hooks explícitos acima são o único gatilho fiável: usa-os em vez de Config.AutomaticParking.
Keys.GiveKeys(source, entity, plate)Dá as chaves do veículo a um jogador quando este aparece. Só corre quando Config.GiveKeysOnSpawn = true. Cada ramo verifica se o recurso de chaves está em started e envolve o export em pcall, pelo que um sistema de chaves em falta nunca estraga o aparecimento.
| Parâmetro | Tipo | Descrição |
|---|---|---|
source |
number |
ID de servidor do jogador que recebe as chaves. |
entity |
number |
Handle de entidade do veículo (pode ser 0 se ainda não tiver aparecido: usa plate). |
plate |
string |
Matrícula do veículo. |
Suportados de origem: qbx_vehiclekeys, qb-vehiclekeys, qs-vehiclekeys, rk-keys. Para custom, acrescenta a tua própria chamada ao export:
function Keys.GiveKeys(source, entity, plate)
-- Config.KeySystem == 'custom'
-- exports['my_key_resource']:GiveKey(source, plate)
endKeys.SetLock(entity, locked)Bloqueia ou desbloqueia uma entidade de veículo no servidor. Só corre quando Config.LockVehiclesOnSpawn = true. locked = true → bloqueado (estado 2), false → desbloqueado (estado 1). Todos os ramos recorrem ao nativo + state bag para que os outros jogadores vejam o veículo estacionado como bloqueado.
| Parâmetro | Tipo | Descrição |
|---|---|---|
entity |
number |
Handle de entidade do veículo. |
locked |
boolean |
true para bloquear, false para desbloquear. |
function Keys.SetLock(entity, locked)
-- Config.KeySystem == 'custom' / 'none' / 'rk-keys' → native fallback:
SetVehicleDoorsLocked(entity, locked and 2 or 1)
Entity(entity).state.doorslockstate = locked and 2 or 1
endFramework.GetLocalIdentifier() → string | nilDevolve, no cliente, o identificador único do jogador local.
function Framework.GetLocalIdentifier()
-- Config.Framework == 'custom'
return nil
endFramework.NotifyClient(message, notifyType)Mostra uma notificação ao jogador local. notifyType: 'info' | 'success' | 'error'
function Framework.NotifyClient(message, notifyType)
-- Config.NotifySystem == 'custom'
endFramework.OnPlayerLoaded(callback)Regista um callback que é disparado quando os dados do jogador estão prontos. Usa-se para a sincronização inicial.
function Framework.OnPlayerLoaded(callback)
-- Config.Framework == 'custom'
CreateThread(function() Wait(0); callback() end)
endKeys.IsLocked(vehicle) → booleanDevolve true se o veículo estiver bloqueado nesse momento. É usado apenas pela verificação periódica opcional de estacionamento automático (Config.AutomaticParking) para detetar quando o jogador bloqueia o carro depois de sair. Verifica tanto o estado de bloqueio nativo como o state bag doorslockstate, sem nunca sair mais cedo por causa de um state bag desbloqueado, para que um bag desatualizado não esconda um bloqueio nativo real.
| Parâmetro | Tipo | Descrição |
|---|---|---|
vehicle |
number |
Handle de entidade do veículo. |
function Keys.IsLocked(vehicle)
-- Native lock: 0=None 1=Unlocked 2=Locked 3=LockedForPlayer 4=StuckForPlayer
if GetVehicleDoorLockStatus(vehicle) >= 2 then return true end
local stateBagLock = Entity(vehicle).state.doorslockstate
if stateBagLock ~= nil and stateBagLock >= 2 then return true end
return false
endSe a deteção automática não for fiável no teu sistema de chaves, dispensa a verificação periódica e usa os hooks explícitos (onVehicleLocked / onVehicleUnlocked) documentados acima em Integração do sistema de chaves.
Fuel.Get(vehicle) → numberDevolve o nível de combustível atual (0–100) de um veículo.
Ordem de deteção automática: ox_fuel → LegacyFuel → ps-fuel → cdn-fuel → native.
function Fuel.Get(vehicle)
-- Config.FuelSystem == 'custom'
return GetVehicleFuelLevel(vehicle)
endFuel.Set(vehicle, level)Define o nível de combustível (0–100) de um veículo. Chama sempre SetVehicleFuelLevel como base e depois o sistema ativo por cima.
function Fuel.Set(vehicle, level)
-- Config.FuelSystem == 'custom'
SetVehicleFuelLevel(vehicle, level + 0.0)
end