Zerix Development

Hoe dienst werkt

Stappen van staffdienst, inclusief checks, kleding, metadata, panel-sync en reconnect.

Command

lib.addCommand('staffdienst', {
    help = 'Ga in of uit dienst als staff',
}, function(source)
    toggleDuty(source)
end)

Het is een toggle. Er is geen apart /staffdienst aan of uit. Vanuit het panel doet de knop Uit dienst hetzelfde: panel sluit en voert ExecuteCommand('staffdienst') uit.

Serverflow (setDuty)

  1. Busy-lock — als je al aan het wisselen bent (\~2,5s), krijg je *“Je bent al bezig met in- of uitdienst gaan.”*
  2. Staff-check — isStaff(source). Bij falen: *“Je hebt geen toegang tot staffdienst.”*
  3. De framework-player moet bestaan (ESX xPlayer, Qbox GetPlayer, of QBCore GetPlayer).
  4. Zelfde state als gevraagd → { ok = true, unchanged = true }, geen animatie.
  5. Kleding ophalen
  • Aan: lib.callback.await('Z-staff:client:getClothing', source)
  • Uit: clothing uit metadata staffdienst
  1. Lokaal toepassen
  • dutyBySource[src]
  • Player(src).state:set('staffdienst', bool, true) (replicated)
  • metadata staffdienst = { onduty, clothing } via setMeta (ESX) of SetMetaData (QB/Qbox)
  1. Events:
  • Z-staff:server:dutyChanged (server, intern)
  • exports['Z-staff']:setDuty(src, bool)
  • Z-staff:client:setDuty (client visuals)
  • bij uit: erp-staff:client:dutyOff

Clientflow (setDuty event)

  1. State bag staffdienst zetten.
  2. Progressbar (clothingshirt / try_shirt_positive_d), duur Config.progress.duration (default 1600 ms).
  • canCancel = false
  • move / car / combat disabled
  • useWhileDead = false
  1. Aan: huidige kleding bewaren → applyStaffOutfit().
  2. Uit: restoreClothing() (opgeslagen snapshot, of illenium appearance als fallback).
  3. Notify on/off duty.

Als Config.progress.enabled = false slaat de animatie over en gaat de kleding direct om.

Reconnect / resource start

ESX

TriggerWat er gebeurt
esx:playerLoadedNa 2s getDutyState → outfit opnieuw als onduty
onResourceStart (dienst)Na 1,5s sync als speler geladen is
esx:onPlayerLogoutlokale duty/clothing/busy wissen
playerDroppedduty-cache wissen, panel krijgt dutyChanged false als je in dienst was

Qbox

TriggerWat er gebeurt
qbx_core:client:playerLoaded / QBCore:Client:OnPlayerLoadedSync duty/outfit na load
onResourceStart (dienst)Sync als speler geladen is
qbx_core:client:playerLoggedOut / QBCore:Client:OnPlayerUnloadlokale / server duty wissen
playerDroppedduty-cache wissen, panel krijgt dutyChanged false als je in dienst was

QBCore

TriggerWat er gebeurt
QBCore:Client:OnPlayerLoadedSync duty/outfit na load
onResourceStart (dienst)Sync als speler geladen is
QBCore:Client:OnPlayerUnload / QBCore:Server:OnPlayerUnloadlokale / server duty wissen
playerDroppedduty-cache wissen, panel krijgt dutyChanged false als je in dienst was

Metadata staffdienst.clothing bevat components + props. Daardoor blijft het civiele outfit bewaard tot je uit dienst gaat, ook als de client even herstart.

Busy-lock

Server én client hebben een busy-vlag. De server wist busy[source] na 2500 ms. Spam van /staffdienst tijdens de animatie wordt geweigerd.

Fallback als het panel niet draait

Draait het panel niet, dan:

  • Duty lokaal (kleding + metadata) werkt nog
  • ACE/rank vanuit het panel wordt niet gezet
  • grantStaff / setDuty op het panel worden overgeslagen

Voor productie: altijd beide starten.

State die andere scripts kunnen lezen

-- server
Player(src).state.staffdienst == true
exports['Z-staff']:IsOnDuty(src)

-- client
LocalPlayer.state.staffdienst == true
exports['Z-staff']:IsOnDuty()

Het panel leest exact deze waarden in Utils.isOnStaffDuty en client/main.lua isOnDuty().