pickpocket.lua
The complete default pickpocket.lua for Petty Crime (sd-pettycrime). Use this as a reference or a starting point for your own configuration.
TIP
This is the full, unedited config file. For a detailed explanation of each option, see the Configuration page.
lua
return {
Cooldown = {
Enable = false, -- Personal cooldown between attempts (true = use Time below).
Time = 30, -- Seconds between attempts when Cooldown.Enable = true.
},
Time = 5, -- (Legacy) progress-bar duration — unused since the minigame replaced it. Kept for compat with any third-party readers.
Chance = 75, -- (Legacy) overall % chance to find anything — superseded by the minigame outcome.
BaseXP = 8, -- Base XP awarded on every successful pick.
-- How many items the server pre-rolls per attempt — randomised each
-- time within this range. Each rolled item gets one card above the bar
-- and one green "safe zone" on the bar that the marker must be inside
-- when the player presses grab. Both bounds inclusive.
--
-- Larger ranges add variety ("how many did I get this time?"); a
-- tight range like { min = 4, max = 4 } pins it to a fixed count.
MinigameItemRange = { min = 3, max = 5 },
-- Minigame selector. `Start` runs when a pickpocket attempt begins; it
-- receives ctx (ctx.items = the server-rolled loot) and returns the
-- minigame result. Swap the body for any other built-in (see
-- client/minigame.lua: lockpick, lockpickBar, holdSteady, mash, stealth,
-- dial, wires, sequence) or your own — without touching the crime code.
-- Set Enable = false to skip the minigame entirely (auto-success).
--
-- Note: only mg.pickpocket reports which slots were grabbed (partial
-- loot). Other minigames are pass/fail, so on success the player gets all
-- rolled items, otherwise none.
Minigame = {
Enable = true,
Start = function(ctx)
return require('client.minigame').pickpocket({
items = ctx.items,
-- Width of each safe zone, in degrees of the marker's full
-- pass across the bar (360°). Narrower = harder.
greenArcDeg = 30,
-- Marker speed in deg/sec (360° = one full pass); compounds
-- via the multiplier after each loot.
rotationSpeedDegSec = 180,
-- Speed multiplier after each loot (direction also flips).
speedUpMultiplier = 1.35,
-- Time limit in seconds; running out = caught. 0 = no limit.
timeLimitSec = 15,
-- Per-item chance (0..1) a card starts hidden as "???".
mysteryChance = 0.5,
})
end,
},
GiveXPForItems = true, -- Adds the per-item XP value when an item drops.
GiveXPForCash = true, -- Adds 1 XP per $ stolen (set false for flat per-pick XP).
Logging = true, -- lib.logger entries on success/fail.
PoliceAlert = {
Enable = true,
Chance = 15, -- 0-100 chance an alert fires on a successful pick.
Send = function()
local alertMessage = 'Pickpocketing reported'
print('Police Alert: ' .. alertMessage)
-- Example: cd_dispatch integration (uncomment to use)
--[[
local data = exports['cd_dispatch']:GetPlayerInfo()
TriggerServerEvent('cd_dispatch:AddNotification', {
job_table = {'police'},
coords = data.coords,
title = '10-15 - Pickpocketing',
message = ('A %s pickpocketing at %s'):format(data.sex, data.street),
flash = 0,
unique_id = data.unique_id,
sound = 1,
blip = {
sprite = 431,
scale = 1.2,
colour = 3,
flashes = false,
text = '911 - Pickpocketing',
time = 5,
radius = 0,
}
})
--]]
end,
},
-- Tiered loot tables. Each tier carries its own cash range *and* a level-
-- keyed item bucket (`[1]`, `[2]`, `[3]`). The level bucket is what
-- `rewards.give` rolls against — same shape as mailbox rewards, so a
-- single weighted-chance pick lands one item per success.
--
-- HOW WEIGHTED CHANCE WORKS
-- The `chance` field is a *weight*, not a percentage — higher weight =
-- proportionally more likely. e.g. `chance=20` is twice as likely as
-- `chance=10` when both are in the same bucket.
Tiers = {
low = {
cash = { min = 4, max = 15 },
[1] = {
{ item = 'metalscrap', chance = 25, min = 1, max = 2, xp = 1 },
{ item = 'copper', chance = 15, min = 1, max = 1, xp = 2 },
},
[2] = {
{ item = 'metalscrap', chance = 20, min = 2, max = 3, xp = 1 },
{ item = 'copper', chance = 15, min = 1, max = 2, xp = 2 },
{ item = 'aluminum', chance = 10, min = 1, max = 1, xp = 3 },
},
[3] = {
{ item = 'metalscrap', chance = 18, min = 3, max = 4, xp = 1 },
{ item = 'copper', chance = 15, min = 2, max = 3, xp = 2 },
{ item = 'aluminum', chance = 12, min = 1, max = 2, xp = 3 },
{ item = 'steel', chance = 8, min = 1, max = 1, xp = 5 },
},
},
medium = {
cash = { min = 12, max = 32 },
[1] = {
{ item = 'rolex', chance = 15, min = 1, max = 1, xp = 8 },
{ item = 'phone', chance = 20, min = 1, max = 1, xp = 6 },
},
[2] = {
{ item = 'rolex', chance = 18, min = 1, max = 2, xp = 8 },
{ item = 'phone', chance = 15, min = 1, max = 1, xp = 6 },
{ item = 'goldchain', chance = 12, min = 1, max = 1, xp = 10 },
},
[3] = {
{ item = 'rolex', chance = 20, min = 1, max = 3, xp = 8 },
{ item = 'phone', chance = 15, min = 1, max = 2, xp = 6 },
{ item = 'goldchain', chance = 15, min = 1, max = 2, xp = 10 },
{ item = 'laptop', chance = 10, min = 1, max = 1, xp = 12 },
},
},
high = {
cash = { min = 25, max = 65 },
[1] = {
{ item = 'diamond_ring', chance = 12, min = 1, max = 1, xp = 15 },
{ item = 'goldchain', chance = 18, min = 1, max = 1, xp = 10 },
},
[2] = {
{ item = 'diamond_ring', chance = 15, min = 1, max = 1, xp = 15 },
{ item = 'goldchain', chance = 15, min = 1, max = 2, xp = 10 },
{ item = '10kgoldchain', chance = 10, min = 1, max = 1, xp = 20 },
},
[3] = {
{ item = 'diamond_ring', chance = 18, min = 1, max = 2, xp = 15 },
{ item = 'goldchain', chance = 15, min = 2, max = 3, xp = 10 },
{ item = '10kgoldchain', chance = 12, min = 1, max = 2, xp = 20 },
{ item = 'diamond', chance = 8, min = 1, max = 1, xp = 25 },
},
},
},
-- Zones grouped by tier. Keys are GTA's `GetNameOfZone()` short codes —
-- they have to match the engine return values exactly. Anything *not*
-- listed defaults to the `low` tier, so leaving a zone off gives it
-- the cheapest loot pool rather than no loot at all.
--
-- Re-tiering a zone is a one-line move between arrays.
ZoneTiers = {
high = {
'ROCKF', -- Rockford Hills
'CHIL', -- Vinewood Hills
'HAWICK', -- Hawick
'PBLUFF', -- Pacific Bluffs
'TONGVAH', -- Tongva Hills
'RGLEN', -- Richman Glen
'RICHM', -- Richman
'HORS', -- Vinewood Racetrack
'STAD', -- Maze Bank Arena
'MOVIE', -- Richards Majestic
'BHAMCA', -- Banham Canyon
'GOLF', -- GWC and Golfing Society
},
medium = {
'AIRP', -- Los Santos International Airport
'BEACH', -- Vespucci Beach
'DELBE', -- Del Perro Beach
'DELPE', -- Del Perro
'MIRR', -- Mirror Park
'MORN', -- Morningwood
'ALTA', -- Alta
'BURTON', -- Burton
'PBOX', -- Pillbox Hill
'LEGSQU', -- Legion Square
'KOREAT', -- Little Seoul
'VINE', -- Vinewood
'WVINE', -- West Vinewood
'DTVINE', -- Downtown Vinewood
'EAST_V', -- East Vinewood
'DOWNT', -- Downtown
'TEXTI', -- Textile City
'HARMO', -- Harmony
},
-- Everything else (Davis, Strawberry, Chamberlain, El Burro, Stab
-- City, Sandy Shores, Grapeseed, Paleto, the wilds, etc.) falls
-- through to the `low` tier automatically. Promote a zone by
-- adding its short code to one of the lists above.
},
}