Config
Explanations and examples for the current catalytic configuration.
Edit zyke_catalytic/shared/unlocked/config.lua. Distances are metres, durations ending in Ms are milliseconds, and chances are percentages unless stated otherwise. Camera offsets are metres from the cut.
Keybinds can be changed in GTA / FiveM settings. Framework, inventory, target, and webhook settings live in zyke_lib. Grinder, disc, and battery settings live in zyke_anglegrinder.
#Full Default Config
#Config.Settings.catalytic
#enabled
Enables the resource. When disabled, jacks, theft, installs, effects, and the fence are unavailable.
Example:
luaenabled = true
#admin.enabled
Enables the admin panel and the admin vehicle target.
Example:
luaenabled = true
#admin.command
Command that opens the admin panel.
Example:
luacommand = "catadmin"
#admin.permission
Permission checked on both client and server for the admin panel, vehicle target, and test commands. This is a permission identifier, not a job name.
Example:
luapermission = "command"
#admin.refreshMs
Milliseconds between automatic refreshes while the admin panel is open.
Example:
luarefreshMs = 3000
#settings.commands
Commands that open the personal settings menu. The menu is also at the bottom of the fence menu. Use an empty table for no command.
Example:
luacommands = {"catalytic", "catsettings"}
#Converter Sizes
Each entry under Config.Settings.catalytic.sizes defines one converter size. Defaults use small, medium, and large. In the paths below, <size> means one of these keys.
| Setting | Small | Medium | Large |
|---|---|---|---|
| Item | catalytic_converter_small | catalytic_converter_medium | catalytic_converter_large |
| Base price | 350 | 600 | 900 |
| Cut checks per pipe | 1 easy | 2 easy | 2 medium |
| Disc wear | 6–12 | 10–16 | 14–22 |
#sizes.<size>.item
Inventory item given for a stolen converter of this size. The item stores the vehicle, plate, grade, value, and condition in its metadata.
Example:
luaitem = "catalytic_converter_small"
#sizes.<size>.price
Fence base payout for a converter in perfect condition, before the vehicle's value multiplier and grade value.
Example:
luaprice = 350
#sizes.<size>.prop
Converter model. Grade suffixes are added to this name.
Example:
luaprop = "zyke_catalytic_small"
#sizes.<size>.stages
One entry per pipe cut, verified by
zyke_anglegrinder.secondsplus the grinder'ssecondsPerCheckfor eachcheckspreset make up the cut's length; the hardest preset sets its difficulty.Example:
luastages = { {checks = {"easy"}, seconds = 1}, {checks = {"easy"}, seconds = 1}, }
#sizes.<size>.durabilityLoss
Disc wear range for the whole theft. Clean cuts halve it.
Example:
luadurabilityLoss = {min = 6, max = 12}
#Grades
Grades are rolled once per car and shown on the converter under it.
#grades.engineBias
Tilts the roll toward better grades for a healthy engine and worse grades for a wrecked one.
0leaves it to chance.Example:
luaengineBias = 0.5
#grades.list
Grades from best to worst.
weightis the share of cars with that grade,valuemultiplies the fence payout, andsuffixis added to the size's prop and item image names.labelis a locale key. The defaults range frompristine(1.35) toholed(0.35).Example:
lualist = { {name = "pristine", label = "grade:pristine", weight = 4, value = 1.35, suffix = "_pristine"}, {name = "clean", label = "grade:clean", weight = 6, value = 1.25}, {name = "holed", label = "grade:holed", weight = 5, value = 0.35, suffix = "_holed"}, }
#Guards
Anti-theft guards are cut through before the pipes. A car's guard is rolled the first time a thief goes under it and kept by plate and model, along with completed cuts, until the resource restarts.
#guards.enabled
Enables anti-theft guards.
Example:
luaenabled = true
#guards.chance
Percent of cars with a guard.
Example:
luachance = 15
#guards.valueChance
Extra percent added for every whole value multiplier above 1, so more valuable converters are guarded more often.
Example:
luavalueChance = 15
#guards.types
Guard types:
cable(two stainless cables),cage(three welded hoops), andshield(a plate cut across at both ends).weightis each type's share of guarded cars,stageis the grind stage of each cut in the same form as size stages, anddurabilityLossis the extra disc wear for all its cuts.Example:
luatypes = { cable = {label = "guard:cable", weight = 50, stage = {seconds = 1}, durabilityLoss = {min = 2, max = 4}}, cage = {label = "guard:cage", weight = 32, stage = {checks = {"medium"}}, durabilityLoss = {min = 6, max = 10}}, shield = {label = "guard:shield", weight = 18, stage = {checks = {"hard"}, seconds = 1}, durabilityLoss = {min = 10, max = 16}}, }
#guards.lunge
Most condition points the converter loses when the disc breaks through a cable or hoop and is pushed past the gap into the converter.
Example:
lualunge = 12
#guards.camera
Close-up on a hoop or shield during the cut. Cables use the converter cut camera.
Example:
luacamera = { offset = {x = 0.3, y = 0.34, z = -0.2}, look = {x = 0.0, y = -0.04, z = 0.0}, fov = 50.0, blendInMs = 900, blendOutMs = 700, }
#guards.plateCut
Shield plate cut. The disc only cuts once plunged through the plate. Plunged more than
depthfurther, it cuts atdragSpeedof the pace and wearsdragWeartimes faster.sensitivityis metres moved per unit of mouse movement.Example:
luaplateCut = { depth = 0.01, dragSpeed = 0.6, dragWear = 2.0, sensitivity = {push = 0.048, plunge = 0.016}, }
#Vehicles
#vehicles.classes
Vehicle class to converter size and value multiplier.
valuemultiplies what the converter is worth at the fence and on contract hand-ins, and is stored on the item. Classes left out, such as motorcycles, boats, and aircraft, cannot be cut.Example:
luaclasses = { [0] = {size = "small"}, -- Compacts [2] = {size = "large"}, -- SUVs [7] = {size = "medium", value = 2.0}, -- Super }
#vehicles.models
Spawn name to size and value, replacing the class entry. Hybrids carry the most precious metal by default.
Example:
luamodels = { dilettante = {size = "small", value = 2.5}, }
#vehicles.excluded
Spawn names without a converter, such as electric vehicles. Vehicles without an exhaust bone are skipped too.
Example:
luaexcluded = {"voltic", "raiden", "cyclone", "neon"}
#vehicles.requireEngineOff
Only allows parked vehicles with the engine off. Vehicles must always have no driver and be stationary.
Example:
luarequireEngineOff = true
#vehicles.blockOwned
Refuses vehicles owned by a player, looked up by plate in
owned_vehicleson ESX orplayer_vehicleson QBCore and Qbox. Applied in the server can-check hooks.Example:
luablockOwned = true
#vehicles.position
Converter position under the body.
forwardis a share of the half length ahead of the centre,insetis metres in from the side, andheightis metres above the underbody.Example:
luaposition = {forward = 0.3, inset = 0.35, height = 0.25}
#vehicles.reach
Furthest distance from the cut point at which a player can start the theft.
Example:
luareach = 1.6
#Theft
#theft.alarmChance
Percent chance per theft that the car alarm goes off when the grinder first bites into the metal. Alarms call
OnConverterAlert.Example:
luaalarmChance = 35
#theft.witnessDistance
Overrides
zyke_anglegrinder's witness distance for converter cuts.falsekeeps the grinder's value.Example:
luawitnessDistance = false
#theft.pullOut
Converter held in the left hand as the player slides out, and the stow animation played once standing. The prop is removed
despawnMsinto the animation.Example:
luapullOut = { stow = {dict = "anim@heists@humane_labs@finale@keycards", clip = "ped_a_pass", ms = 1200, despawnMs = 1000}, bone = 18905, offset = {x = 0.18, y = 0.02, z = -0.02}, rotation = {x = -80.0, y = 0.0, z = 90.0}, }
#theft.condition
Converter condition from the vehicle's engine health. A wrecked engine still yields at least
minpercent;wearMaxis the most random wear removed.Example:
luacondition = {min = 40, wearMax = 8}
#theft.scene.jack.item
Reusable jack item. Placing it takes the item; picking the jack back up returns it.
Example:
luaitem = "catalytic_jack"
#theft.scene.jack.aimDistance
Furthest distance from the player to the aimed jacking point.
Example:
luaaimDistance = 4.0
#theft.scene.jack.promptDistance
Distance from a raised car's lie spot within which its go-under marker shows.
Example:
luapromptDistance = 10.0
#theft.scene.jack.skipClearance
Floor clearance in metres at which a parked car can be gone under without a jack. A jacked Sultan gives about 0.26, a Baller 0.41, and a Sandking 0.90.
Example:
luaskipClearance = 0.35
#theft.scene.jack.roll
Most tilt in degrees as the near side rises on the jack.
Example:
luaroll = 12.0
#theft.scene.jack.strokes
Handle strokes needed to lift the car.
Example:
luastrokes = 6
#theft.scene.jack.releaseMs
Time the opened valve takes to lower the car.
Example:
luareleaseMs = 2500
#theft.scene.jack.kneelDistance
Distance back from the jack along its handle where the player kneels.
Example:
luakneelDistance = 0.72
#theft.scene.jack.pump
Pump animation played over the kneel; the lever follows its stroke.
kneel,release,putDown,pickUp, anddrawuse the same format for the other jack animations.Example:
luapump = {dict = "zyke_catalytic_jack_anims", clip = "pump", flag = 49}
#theft.scene.jack.hold
Carry animation and bone attachment while aiming the jack.
Example:
luahold = { anim = {dict = "move_weapon@jerrycan@generic", clip = "idle"}, bone = 57005, offset = {x = 0.27, y = -0.01, z = -0.025}, rotation = {x = -0.5, y = -81.5, z = -12.0}, }
#theft.scene.anims
Under-car enter, loop, and exit animations.
phaseholds an animation still at that share of its clip.Example:
luaanims = { enter = {dict = "amb@world_human_vehicle_mechanic@male@enter", clip = "enter"}, loop = {dict = "amb@world_human_vehicle_mechanic@male@base", clip = "base", phase = 0.69}, exit = {dict = "amb@world_human_vehicle_mechanic@male@exit", clip = "exit"}, }
#theft.scene.lieOut
Distance out from the car's side where the player lies.
Example:
lualieOut = 0.35
#theft.scene.grip
Grinder grip while lying, passed to
zyke_anglegrinderso every client sees it.Example:
luagrip = { bone = 57005, offset = {x = 0.12, y = 0.02, z = -0.02}, rotation = {x = 0.0, y = 180.0, z = 90.0}, }
#theft.scene.pipeGap
Distance between the pipe and the disc edge, toward the floor.
Example:
luapipeGap = 0.03
#theft.scene.camera
Under-car camera.
xpoints toward the car's centre,yalong the pipe away from the converter, andzup.Example:
luacamera = { offset = {x = 0.35, y = 0.55, z = -0.18}, look = {x = 0.0, y = -0.05, z = 0.0}, fov = 50.0, blendInMs = 900, blendOutMs = 700, }
#theft.scene.light
Head torch lighting the underside while the player works.
Example:
lualight = {color = {r = 255, g = 228, b = 196}, range = 2.2, intensity = 3.0}
#theft.minigame
converterCutdrives the grinder in a close-up on the pipes.pipeCutplays a ring panel where the disc is steered around the pipe.Example:
luaminigame = "converterCut"
#Converter Cut
Settings under Config.Settings.catalytic.theft.converterCut. The mouse slides the grinder along the pipe and feeds it into the metal while the press key spins it. The joint cuts clean; off it, the cut is slower, wears the disc faster, and damages the converter.
#converterCut.keys
Keys that spin the disc.
Example:
luakeys = {press = {"LEFTMOUSE", "SPACE"}}
#converterCut.sensitivity
Metres the disc moves per unit of mouse movement.
Example:
luasensitivity = {slide = 0.048, feed = 0.02}
#converterCut.pressure
Feed depth band in metres. Under
min, the disc only rubs; overmax, it binds and costsbindDamagecondition per second.wanderscales how far the disc's grab drifts, so the feed needs steady correction.Example:
luapressure = {min = 0.003, max = 0.012, bindDamage = 8, wander = 1.5}
#converterCut.spot
Within
tolerancemetres of the joint, the cut is clean. Off-spot effects build over the nextfalloffmetres.Example:
luaspot = {tolerance = 0.012, falloff = 0.04}
#converterCut.offSpot
Fully off the joint: cut speed share, disc wear multiplier, and condition lost per pipe. Cutting on the converter's side multiplies the damage by
converterSide.Example:
luaoffSpot = {speed = 0.45, wear = 2.5, damage = 30, converterSide = 1.5}
#converterCut.maxDamage
Most condition points one theft can remove from the converter.
Example:
luamaxDamage = 60
#converterCut.commitDepth
Kerf depth at which the disc is held until dropped clear of the pipe.
Example:
luacommitDepth = 0.003
#converterCut.twist
Sideways movement that binds a committed disc.
Example:
luatwist = 0.012
#converterCut.lean
Degrees the grinder body leans out toward the player.
Example:
lualean = 20.0
#converterCut.mark
Chalk band around the joint, as wide as the clean zone.
falsefor none.Example:
luamark = {r = 245, g = 222, b = 120, a = 160}
#converterCut.camera
Close-up on the pipe being cut.
Example:
luacamera = { offset = {x = 0.32, y = 0.4, z = -0.22}, look = {x = 0.0, y = -0.08, z = 0.0}, fov = 50.0, blendInMs = 900, blendOutMs = 700, }
#Pipe Cut
Settings under Config.Settings.catalytic.theft.pipeCut, used when minigame = "pipeCut". The disc is steered around the pipe while held in. Lingering heats the metal until the disc binds; sweeping too fast skates without cutting.
#pipeCut.segments
Parts around the pipe, each cut through on its own.
Example:
luasegments = 12
#pipeCut.keys
Keys that hold the disc in and steer it. Names are
zyke_libkey names, so each follows the player's own binding.Example:
luakeys = {press = {"LEFTMOUSE", "SPACE"}, left = "A", right = "D"}
#pipeCut.acceleration
How fast the swing builds while steering, in safe sweep speeds per second.
Example:
luaacceleration = 3.0
#pipeCut.friction
How fast the swing dies out after steering.
Example:
luafriction = 2.5
#pipeCut.difficulties
Per difficulty:
passis the share of a part one pass can cut before binding,skateis how many times the slowest safe sweep the disc can go before skating, andcoolis how many parts' cut time a bound part needs to cool.Example:
luadifficulties = { easy = {pass = 0.7, skate = 2.8, cool = 2.5}, medium = {pass = 0.55, skate = 2.3, cool = 3.0}, hard = {pass = 0.45, skate = 1.9, cool = 3.5}, }
#pipeCut.glowSeconds
Seconds a freshly cut part keeps glowing.
Example:
luaglowSeconds = 4.0
#Effects
What running without a converter does to a vehicle, seen and heard by every nearby player.
#effects.enabled
Enables the missing-converter effects.
Example:
luaenabled = true
#effects.engineSound
Engine sound used while the converter is missing, as any vehicle audio name.
falsekeeps the stock sound.Example:
luaengineSound = "tornado6"
#effects.engineSoundStock
Stock audio names restored after install, keyed by lowercase model name. Only needed for addon vehicles whose
audioNameHashdiffers from the model name.Example:
luaengineSoundStock = { mycar = "comet2", }
#effects.engineAudioDamage
Rough engine note, from
0(stock) to1(fully damaged).Example:
luaengineAudioDamage = 0.9
#effects.exhaustPops
Enables pops and crackles off throttle for vehicles that do not pop by default.
Example:
luaexhaustPops = true
#effects.backfire
Exhaust flames when the driver lifts off above
minRpm(a0to1share of the rev range), and on misfires.Example:
luabackfire = { enabled = true, chance = 70, minRpm = 0.45, cooldownMs = 1000, asset = "core", name = "veh_backfire", scale = 1.0, }
#effects.misfire
Brief engine cut-outs under throttle. Interval and duration are rolled between
minandmax.Example:
luamisfire = { enabled = true, intervalMs = {min = 2500, max = 7000}, durationMs = {min = 120, max = 320}, }
#effects.smoke
Dark exhaust puffs while the throttle is above
minThrottle.offsetmoves the smoke from each exhaust tip,rotationturns the particle, andcolourtints it from0to1per channel.Example:
luasmoke = { enabled = true, minThrottle = 0.8, delayMs = 400, intervalMs = 1400, durationMs = 600, asset = "scr_recartheft", name = "scr_wheel_burnout", scale = 0.4, offset = vec3(0.0, -0.3, 0.12), rotation = vec3(-30.0, 0.0, 180.0), colour = {r = 0.08, g = 0.08, b = 0.08}, alpha = 0.45, }
#effects.powerMultiplier
Engine torque multiplier for the driver.
1.0for no power loss.Example:
luapowerMultiplier = 0.7
#effects.checkEngineNotify
Notifies the driver when they start driving a vehicle without its converter.
Example:
luacheckEngineNotify = true
#persistence.enabled
Keeps missing converters by plate, so a garage respawn still runs rough.
Example:
luaenabled = true
#persistence.days
Days before a missing-converter record expires.
falsekeeps it until a converter is installed.Example:
luadays = 14
#Install
#install.enabled
Enables installing replacement converters from the item and the vehicle target.
Example:
luaenabled = true
#install.items
Items that can be installed. Stolen converters also work when listed here.
Example:
luaitems = {"catalytic_converter_new"}
#install.seconds
Install duration in seconds.
Example:
luaseconds = 12
#install.reach
Furthest distance from the vehicle's side at which an install can start.
Example:
luareach = 2.5
#install.anim
Animation played during the install.
Example:
luaanim = {dict = "anim@amb@clubhouse@tutorial@bkr_tut_ig3@", clip = "machinic_loop_mechandplayer", flag = 1}
#install.prop
Prop held during the install.
falsefor none.Example:
luaprop = {model = "zyke_catalytic_new", bone = 18905, pos = vec3(0.16, 0.02, -0.03), rot = vec3(-80.0, 0.0, 90.0)}
#Fence
Fence peds buy stolen converters, hand out contracts, and sell tools. Item entries use configured item names, so renamed items need their entries updated too.
#fence.enabled
Enables fence peds.
Example:
luaenabled = true
#fence.payoutAccount
Account the fence pays into, such as
cash,bank, orblack_money.Example:
luapayoutAccount = "cash"
#fence.conditionFloor
Share of the payout a converter in 0% condition still fetches.
Example:
luaconditionFloor = 0.5
#fence.wornShare
Share of the fence's price a used part at 100% durability fetches when sold back.
Example:
luawornShare = 0.8
#fence.market
Shared demand for converters sold outright, saved in the database. The fence pays at most
maxShareof a converter's value; every sale lowers that bydropPerSale, and it recovers byrecoverPerHour. BelowminShare, he buys nothing until it recovers toreopenShare. Contracts are not affected.Example:
luamarket = {maxShare = 0.4, minShare = 0.1, reopenShare = 0.15, dropPerSale = 0.01, recoverPerHour = 0.05}
#fence.sellRep
Reputation rolled per converter sold outright. Requires contracts to be enabled.
Example:
luasellRep = {min = 1, max = 2}
#fence.recharge
Battery recharges for fences with
recharge = true.itemiszyke_anglegrinder's battery item,priceis flat per recharge, andchargeAmountis the percent restored.Example:
luarecharge = {item = "anglegrinder_battery", seconds = 8, price = 100, chargeAmount = 100}
#fence.positions
Fence peds.
coordsincludes the heading.hourslimits him to real-life server hours from0to24, and can run past midnight; leave it out to keep him there all day.buysConverters,contracts, andrechargetoggle his services.itemsare sold,buybackitems are bought per piece, andwornBuybackparts are bought by durability, dropping to the broken item's price at 0%.Example:
luapositions = { { label = "Scrap Buyer", model = "s_m_y_xmech_02", coords = vec4(2355.86, 3144.49, 48.21, 172.48), scenario = "WORLD_HUMAN_SMOKING", -- hours = {from = 20, to = 6}, blip = {enabled = true, sprite = 527, color = 1, scale = 0.7}, buysConverters = true, contracts = true, recharge = true, items = { {name = "catalytic_jack", price = 450}, }, buyback = { {name = "anglegrinder_disc_broken", price = 10}, }, wornBuyback = { {name = "anglegrinder_disc", broken = "anglegrinder_disc_broken"}, }, }, }
#Contracts
Contracts are handed out to each player separately. Reputation decides access: board offers, concurrent jobs, the daily limit, and which pool entries appear. See Fence & Contracts.
#contracts.enabled
Enables contracts and reputation.
Example:
luaenabled = true
#contracts.offerSlots
Job slots on the board. Slots the player's level has not unlocked show as locked.
Example:
luaofferSlots = 4
#contracts.limitHours
Hours each taken job counts toward the daily limit.
Example:
lualimitHours = 16
#contracts.levels
Reputation levels; the highest reached wins.
offersis how many slots hold a job,activehow many can run at once, anddailyhow many can be taken withinlimitHours.labelis a locale key.Example:
lualevels = { {rep = 0, label = "level:stranger", offers = 1, active = 1, daily = 2}, {rep = 100, label = "level:runner", offers = 2, active = 1, daily = 3}, {rep = 250, label = "level:regular", offers = 3, active = 2, daily = 4}, {rep = 500, label = "level:trusted", offers = 4, active = 2, daily = 6}, {rep = 1000, label = "level:partner", offers = 4, active = 3, daily = 8}, }
#contracts.boardMinutes
Minutes before offered jobs are replaced.
Example:
luaboardMinutes = 45
#contracts.standards
Condition standards the fence asks for.
conditionis the lowest converter condition that meets it, andvaluemultiplies the job's payout and reputation.labelandbriefare locale keys.Example:
luastandards = { {name = "pristine", condition = 75, value = 1.4, label = "standard:pristine", brief = "standard:pristineBrief"}, {name = "any", condition = 20, value = 0.7, label = "standard:any", brief = "standard:anyBrief"}, }
#contracts.scoring
How a hand-in is scored against the standard. Meeting it exactly pays the job as offered. Each point over adds payout and reputation up to
exceed; each point under removes them down toshort, where reputation turns into a loss. Each grade worse than accepted counts asgradeSteppoints under.wrongapplies to a converter that is not what he asked for, andexcellentAtis the points over that rate as excellent.Example:
luascoring = { exceed = {range = 25, payout = 1.3, rep = 1.5}, short = {range = 30, payout = 0.4, rep = -1.0}, gradeStep = 10, excellentAt = 15, wrong = {payout = 0.25, rep = -1.0}, }
#contracts.failedRep
Share of the job's reputation lost when it runs out of time or is dropped.
Example:
luafailedRep = 0.75
#contracts.idle
Reputation decay. After
graceHourssince the last finished job,pointsare lost everyeveryHoursuntil the next one.Example:
luaidle = {enabled = true, graceHours = 24, everyHours = 24, points = 15}
#contracts.trendDays
Days of history summed for the trend in the fence menu.
Example:
luatrendDays = 7
#contracts.tracker
On-screen list of running jobs with their steps and time left.
positionistop-left,top-right,center-left,center-right,bottom-left, orbottom-right;offsetis the gap to the screen edges in percent of the screen height.keyis the default toggle key;""leaves it for players to bind.Example:
luatracker = { enabled = true, position = "top-left", offset = {x = 2.5, y = 2.5}, key = "", }
#contracts.target
Target jobs spawn a locked vehicle at a free location and give the player a search area
radiusmetres wide around it.Example:
luatarget = { radius = 120.0, locations = { vec4(212.0, -810.0, 30.65, 340.0), }, }
#contracts.pool
Jobs the fence can offer.
typeisspecfor any converter of the listedsizes,modelfor one cut from a listed model, ortargetfor the spawned vehicle.levelis the lowest reputation level that offers it,weighthow often it is picked,standardsthe standards he picks from,gradethe worst accepted grade, andminutesthe time to deliver.payoutandrepare rolled from their ranges before the standard's value.Example:
luapool = { {type = "spec", level = 1, weight = 10, sizes = {"small", "medium"}, standards = {"rough", "any"}, payout = {min = 450, max = 700}, rep = {min = 8, max = 12}, minutes = 90}, {type = "target", level = 3, weight = 6, models = {"baller", "granger", "bison", "felon", "tailgater"}, standards = {"clean", "decent"}, payout = {min = 1300, max = 1800}, rep = {min = 20, max = 28}, minutes = 45}, }