Documentation

Can-Check Hooks

Hook functions that run before catalytic actions are executed. Return false to deny with an optional reason.

Can-check hooks allow you to control player actions in zyke_catalytic before they execute. Return false with an optional locale key to deny an action and notify the player.

#File Locations

SideFile
Serverserver/unlocked/can_checks.lua
Clientclient/unlocked/can_checks.lua

Both files are unencrypted and safe to edit directly. Edit the existing functions inside Catalytic Converters.

Types / Classes

All types / classes can be found in types/types.lua. Vehicle arguments are entity handles; plyId is the requesting player's server ID.


#How Reason Strings Work

#Server-side reasons

The server returns the reason through the action callback. The client passes it to Z.notify(), so use a locale key. Missing reasons fall back to "noPermission".

#Client-side reasons

Client checks also use locale keys and fall back to "noPermission". They provide immediate feedback; enforce trusted restrictions in the corresponding server hook. Add custom reason keys to every resource locale.

This server-side example only allows converter theft between 22:00 and 06:00 server time.

Example:

lua
---@param plyId PlayerId
---@param vehicle integer
---@return boolean allowed
---@return string? reason
function CanStealConverter(plyId, vehicle)
    local hour = tonumber(os.date("%H"))
    if (hour >= 6 and hour < 22) then return false, "noPermission" end

    return canTargetVehicle(vehicle)
end

#Execution & Validation

Keep hooks synchronous where possible. Returning true continues the normal flow; built-in vehicle, item, distance, and grinder checks still apply.

By default, CanStealConverter and CanPlaceJack call the local canTargetVehicle helper, which applies vehicles.blockOwned through a database lookup. Keep that call when adding your own rules, or owned vehicles become valid targets.

Trusted server exports and admin actions bypass player action hooks.


#Server-Sided Hooks

All server-sided hooks are in server/unlocked/can_checks.lua.

#Can Steal Converter

Called when the player starts the theft under a vehicle and again before the converter is handed out.

Example:

lua
---@param plyId PlayerId
---@param vehicle integer @ Vehicle the converter is being cut from
---@return boolean allowed
---@return string? reason
function CanStealConverter(plyId, vehicle)
    return canTargetVehicle(vehicle)
end

#Can Place Jack

Called before a jack is placed under a vehicle and the jack item is taken.

Example:

lua
---@param plyId PlayerId
---@param vehicle integer @ Vehicle the jack goes under
---@return boolean allowed
---@return string? reason
function CanPlaceJack(plyId, vehicle)
    return canTargetVehicle(vehicle)
end

#Can Install Converter

Called when an install starts and again before it completes. item is the converter item being installed.

Example:

lua
---@param plyId PlayerId
---@param vehicle integer @ Vehicle receiving the converter
---@param item Item @ Converter item being installed
---@return boolean allowed
---@return string? reason
function CanInstallConverter(plyId, vehicle, item)
    return true
end

#Can Use Converter Fence

Called before any fence interaction. fenceIndex is the index in fence.positions.

Example:

lua
---@param plyId PlayerId
---@param fenceIndex integer
---@return boolean allowed
---@return string? reason
function CanUseConverterFence(plyId, fenceIndex)
    return true
end

#Can Accept Converter Contract

Called before a player takes a contract. contract is the offer being taken.

Example:

lua
---@param plyId PlayerId
---@param contract ConverterContract @ Offer the player is taking
---@return boolean allowed
---@return string? reason
function CanAcceptConverterContract(plyId, contract)
    return true
end

#Client-Sided Hooks

All client-sided hooks are in client/unlocked/can_checks.lua. The server re-validates every action.

#Can Steal Converter

Called before the player goes under a vehicle.

Example:

lua
---@param vehicle integer @ Vehicle the converter would be cut from
---@return boolean allowed
---@return string? reason
function CanStealConverter(vehicle)
    return true
end

#Can Place Jack

Called before the jack placement is confirmed.

Example:

lua
---@param vehicle integer @ Vehicle the jack would go under
---@return boolean allowed
---@return string? reason
function CanPlaceJack(vehicle)
    return true
end

#Can Install Converter

Called before the install starts.

Example:

lua
---@param vehicle integer @ Vehicle receiving the converter
---@return boolean allowed
---@return string? reason
function CanInstallConverter(vehicle)
    return true
end

#Common Patterns

#Restrict Installs to Mechanics

Uses the server hook so the restriction cannot be bypassed from the client.

Example:

lua
---@param plyId PlayerId
---@param vehicle integer
---@param item Item
---@return boolean allowed
---@return string? reason
function CanInstallConverter(plyId, vehicle, item)
    if (not Z.isJob(plyId, "mechanic")) then return false, "noPermission" end

    return true
end