Can-Check Hooks
Hook functions that run before towing actions are executed. Return false to deny with an optional reason.
Can-check hooks allow you to control player actions in zyke_towing before they execute. All hooks return true by default. Return false with an optional locale key to deny an action and notify the player.
#File Locations
| Side | File |
|---|---|
| Server | server/unlocked/can_checks.lua |
| Client | client/unlocked/can_checks.lua |
Both files are unencrypted and safe to edit directly. Edit the existing functions inside Towing.
Types / Classes
All types / classes can be found in
types/types.lua. Vehicle arguments are entity handles;plyIdis the requesting player's server ID.TowRecorddescribes a rope or cable connection.
#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 allows only steel cables when a player equips a material or requests an attachment.
Example:
lua---@param plyId PlayerId ---@param material string ---@return boolean allowed ---@return string? reason function CanUseTowRope(plyId, material) if (material ~= "metal") then return false, "noPermission" end return true end
#Execution & Validation
Keep hooks synchronous and free of side effects. They may run repeatedly during target selection or winch heartbeats. Returning true continues the normal flow; built-in entity, inventory, access, and safety checks still apply.
Trusted server CreateTowRecord / RemoveTowRecord exports and automatic cleanup bypass player action hooks. Stopping a winch is always allowed.
#Server-Sided Hooks
All server-sided hooks are in server/unlocked/can_checks.lua.
#Can Use Tow Rope
Called when checking whether the player can equip a material and again before attaching vehicles.
materialis the key inConfig.Settings.towing.ropeMaterials, such asropeormetal.Example:
lua---@param plyId PlayerId ---@param material string ---@return boolean allowed ---@return string? reason function CanUseTowRope(plyId, material) return true end
#Can Tow Vehicle
Called before a player attachment request creates a connection or consumes its item.
toweris the pulling vehicle andtowedis the load; bumper ends arefrontorrear.Example:
lua---@param plyId PlayerId ---@param tower integer @ Vehicle doing the pulling ---@param towed integer @ Vehicle being pulled ---@param material string ---@param towerEnd "rear" | "front" ---@param towedEnd "rear" | "front" ---@return boolean allowed ---@return string? reason function CanTowVehicle(plyId, tower, towed, material, towerEnd, towedEnd) return true end
#Can Detach Tow
Called before a player manually detaches a connection.
towis the activeTowRecord. Returningtruecontinues the normal item-refund and removal checks.Example:
lua---@param plyId PlayerId ---@param tow TowRecord ---@return boolean allowed ---@return string? reason function CanDetachTow(plyId, tow) return true end
#Can Winch Tow
Called on each reel-in or pay-out request, including hold heartbeats.
directionisinorout. Use an inexpensive check; stopping the winch does not call this gate.Example:
lua---@param plyId PlayerId ---@param tow TowRecord ---@param direction "in" | "out" ---@return boolean allowed ---@return string? reason function CanWinchTow(plyId, tow, direction) return true end
#Can Change Tow Bed
Called before a player loads, unloads, or moves a bed vehicle.
slotis the destination slot for loading/moving and the occupied slot for unloading. Indices are one-based.unloadis true for unloading;fromSlotidentifies the original slot when repositioning a loaded vehicle.Example:
lua---@param plyId PlayerId ---@param carrier integer ---@param vehicle integer ---@param slot integer ---@param unload boolean ---@param fromSlot? integer @ Existing slot when repositioning a loaded vehicle ---@return boolean allowed ---@return string? reason function CanChangeTowBed(plyId, carrier, vehicle, slot, unload, fromSlot) return true end
#Client-Sided Hooks
All client-sided hooks are in client/unlocked/can_checks.lua.
#Can Use Tow Rope
Called before starting the normal rope or cable carrying flow. The material key is
ropeormetalby default. The detach animation that shows and pockets a returned rope skips this check.Example:
lua---@param material string ---@return boolean allowed ---@return string? reason function CanUseTowRope(material) return true end
#Can Tow Vehicle
Called while validating attachment, including target selection and checks around the progress action. Keep it inexpensive. The vehicle arguments are local entity handles and each end is
frontorrear.Example:
lua---@param tower integer @ Vehicle doing the pulling ---@param towed integer @ Vehicle being pulled ---@param material string ---@param towerEnd "rear" | "front" ---@param towedEnd "rear" | "front" ---@return boolean allowed ---@return string? reason function CanTowVehicle(tower, towed, material, towerEnd, towedEnd) return true end
#Can Detach Tow
Called before the player starts the detachment progress action.
towis the selected connection. Server validation runs again when the player requests removal.Example:
lua---@param tow TowRecord ---@return boolean allowed ---@return string? reason function CanDetachTow(tow) return true end
#Can Winch Tow
Called before starting a local winch action.
directionisinorout. The server hook independently checks subsequent hold requests.Example:
lua---@param tow TowRecord ---@param direction "in" | "out" ---@return boolean allowed ---@return string? reason function CanWinchTow(tow, direction) return true end
#Can Change Tow Bed
Called before requesting a bed load, unload, or slot move.
slotis the one-based destination or unloading slot.unloadis true for unloading;fromSlotis provided when moving a vehicle from another slot. The server independently validates the operation.Example:
lua---@param carrier integer ---@param vehicle integer ---@param slot integer ---@param unload boolean ---@param fromSlot? integer @ Existing slot when repositioning a loaded vehicle ---@return boolean allowed ---@return string? reason function CanChangeTowBed(carrier, vehicle, slot, unload, fromSlot) return true end
#Can Open Tow Bed Menu
Called before opening the carrier slot menu. This client-only hook controls menu access; enforce loading, unloading, and moving restrictions in the server
CanChangeTowBedhook.Example:
lua---@param carrier integer ---@return boolean allowed ---@return string? reason function CanOpenTowBedMenu(carrier) return true end
#Common Patterns
#Restrict Player Attachments to Steel Cables
Edit the server attachment hook to require the
metalmaterial. Mirror the rule in the client hook for feedback during target selection.Example:
lua---@param plyId PlayerId ---@param tower integer @ Vehicle doing the pulling ---@param towed integer @ Vehicle being pulled ---@param material string ---@param towerEnd "rear" | "front" ---@param towedEnd "rear" | "front" ---@return boolean allowed ---@return string? reason function CanTowVehicle(plyId, tower, towed, material, towerEnd, towedEnd) if (material ~= "metal") then return false, "noPermission" end return true end
#Allow Bed Loading and Unloading but Deny Slot Moves
Use
fromSlotto distinguish moving an already loaded vehicle from a new load or unload.Example:
lua---@param plyId PlayerId ---@param carrier integer ---@param vehicle integer ---@param slot integer ---@param unload boolean ---@param fromSlot? integer @ Existing slot when repositioning a loaded vehicle ---@return boolean allowed ---@return string? reason function CanChangeTowBed(plyId, carrier, vehicle, slot, unload, fromSlot) if (fromSlot ~= nil) then return false, "noPermission" end return true end