client/edit.lua
Owner-editable client hooks: notify, downed check, start gate, session events.
Do not rename these globals. Core client code calls them by name. Keep the if not Framework and Config.Framework ~= 'custom' then return end guard at the top.
Config.Framework = "custom" skips the built-in qb/esx object. You still define every function below.
Session state bag (replicated): LocalPlayer.state.gs_metaldetect is false while unequipped, or { item, slot, charge } while scanning.
Job gates that must be authoritative belong on the server (CanUseDetector / CanUseBattery). Use the client hooks for UX: notify style, cuff/vehicle checks, death events.
ClientNotify
Every client toast: equip, put away, dig errors, battery, audio toggle.
function ClientNotify(nType, description)
lib.notify({ type = nType, description = description })
endnType is ox_lib style (success, error, inform). Swap the body for okokNotify, mythic, or your HUD. Returning nothing still sends the message unless you return early.
IsPlayerDown
Blocks starting a scan, and unequips if the player dies mid-scan.
function IsPlayerDown()
-- bundled: ped dead flags, LocalPlayer.state isDead / inLaststand,
-- QBCore metadata isdead / inlaststand
return false
endReturn true when the player should not hold a detector (dead, laststand, knockout). Add your ambulance metadata here if it is not already covered.
CanStartScan
Runs on the client after the server has already allowed the item. Extra UX gate.
function CanStartScan()
if cache.vehicle then
return false, locale('error.in_vehicle')
end
if IsPlayerDown() then
return false
end
-- if IsPedCuffed(cache.ped) then return false, locale('error.busy') end
return true
endReturn true to start. Return false to abort. Optional second return is shown through ClientNotify (error). The bundled file already blocks vehicles and downed players. Uncomment the cuffed check, or add a progress-busy export from your inventory.
This is not a job check. Put jobs in server CanUseDetector.
OnScanStarted / OnScanStopped
Optional. Fire after the prop and LCD are up, and after they are torn down.
function OnScanStarted(session)
-- session.item, session.slot, session.charge, session.label
-- example: exports['your_hud']:SetBusy(true)
end
function OnScanStopped(reason)
-- toggle used the detector item again
-- death IsPlayerDown or a down hook
-- vehicle entered a vehicle
-- export another resource called Stop
-- client F / local stop
-- no_detector
endUse these to pause another activity, hide a HUD, or clear anims. Do not put inventory or loot logic here.
RegisterDownHooks
Called once at start with an unequip function (no args). Wire any death event that IsPlayerDown might miss.
function RegisterDownHooks(unequip)
AddEventHandler('esx:onPlayerDeath', unequip)
AddEventHandler('baseevents:onPlayerDied', unequip)
AddEventHandler('baseevents:onPlayerKilled', unequip)
RegisterNetEvent('hospital:client:SetDeathStatus', function(isDead)
if isDead then unequip() end
end)
RegisterNetEvent('hospital:client:SetLaststandStatus', function(inLaststand)
if inLaststand then unequip() end
end)
-- AddEventHandler('your_ambulance:client:died', unequip)
endLeave the bundled listeners in place. Add yours next to the commented ambulance line.
Server-side pair: server/edit.lua. Wiring examples: Integrations.
