qb-bankrobbery
qb-bankrobbery covers the Fleeca branches, Paleto Bay, and the Pacific Standard, plus the power
stations that can be blown to cause a city blackout. It is the largest of the QBCore robbery
resources and the only one in this set that exposes a documented integration surface through
configurable hook functions instead of hardcoded cross-resource events.
Other robberies live in qb-storerobbery, qb-jewelery, qb-houserobbery, and qb-truckrobbery.
The manifest at the commit linked above declares version 1.3.0.
Dependencies and start order
The manifest declares dependency 'PolyZone' and loads @PolyZone/client.lua and
@PolyZone/BoxZone.lua as client scripts, plus @qb-core/shared/locale.lua as a shared script.
Start order: qb-core, then PolyZone, then qb-bankrobbery.
Beyond the declared dependencies, the shipped configuration hooks call into qb-doorlock, qb-inventory, qb-banking, qb-scoreboard, qb-hud, qb-policejob, and an evidence resource. Those are soft dependencies that live in editable functions, so a server that does not run one of them edits the hook rather than patching the resource.
Configuration layout
Configuration is split across three files loaded into different contexts. This matters, because editing the wrong file has no effect.
| File | Loaded as | Holds |
|---|---|---|
sh_config.lua | shared_scripts | Location data: Config.PowerStations, Config.SmallBanks, Config.BigBanks |
cl_config.lua | client_scripts | Client hook functions and police minimums |
sv_config.lua | server_scripts | Server hook functions, reward tables, camera mapping |
Client side keys
| Key | Default | Meaning |
|---|---|---|
Config.UseTarget | GetConvar('UseTarget', 'false') == 'true' | Read from the server convar, set setr UseTarget true in server.cfg rather than editing the file |
Config.MinimumPaletoPolice | 0 | On-duty police required for Paleto |
Config.MinimumPacificPolice | 0 | On-duty police required for Pacific Standard |
Config.MinimumFleecaPolice | 0 | On-duty police required for a Fleeca branch |
Config.MinimumThermitePolice | 0 | On-duty police required for a thermite action |
Config.OutlawCooldown | 5 | Minutes before the police alarm can fire again |
All four police minimums ship as 0, which means the shipped configuration lets a robbery start
with nobody on duty. Set them before going live.
The cop count itself arrives through police:SetCopCount, which cl_config.lua listens for. On a
server that does not run qb-policejob, nothing ever fires that
event and the count stays at its initial value.
Server side keys
| Key | Default | Meaning |
|---|---|---|
Config.HitsNeeded | 13 | Power stations that must be hit before a blackout triggers |
Config.BlackoutTimer | 10 | Minutes the blackout lasts |
Config.RewardTypes | two entries | item and money, picked at random per locker |
Config.LockerRewards | tier1 to tier3 | Fleeca locker item pools |
Config.LockerRewardsPaleto | tier1 to tier3 | Paleto locker item pools |
Config.LockerRewardsPacific | tier1 to tier3 | Pacific locker item pools |
Config.CameraHits | table | Which power stations disable which police and bank cameras |
Reward tiers are rolled per locker: below 50 gives tier 1, 50 to 79 tier 2, 80 to 94 tier 3, and 95
or above a security_card_01 instead of a tiered item. A separate one-in-fifty roll can substitute a
weapon_stungun. The money branch grants markedbills with a worth between 2300 and 3200 for
Fleeca lockers.
Every item name in these tables must exist in your shared items list, or the reward silently fails to appear.
Integration hooks
These are plain Lua functions in the config files. Replace the body to integrate with your own resources. They are the intended extension point.
Client hooks, cl_config.lua
| Function | Called when |
|---|---|
Config.DoorlockAction(doorId, setLocked) | A bank door should lock or unlock |
Config.OnEvidence(pos, chance) | An action can drop fingerprint evidence. The shipped body skips the drop when QBCore.Functions.IsWearingGloves() is true |
Config.OnDrillingAction() | Every 10 seconds while drilling a deposit box |
Config.OnPoliceAlert(message) | The alarm calls the police |
Config.ShowRequiredItems(items, show) | The required-item hint should appear or disappear |
Server hooks, sv_config.lua
| Function | Called when |
|---|---|
Config.OnRobberyStart(bankId) | A robbery has just begun |
Config.OnRobberyTimeoutEnd(bankId) | The robbery’s cooldown has expired |
Config.OnPoliceCameraHit(hits) | One or more power stations were hit |
Config.OnBlackout(isBlackout) | A blackout starts or ends |
Example
Replacing the stress hook with your own resource:
-- cl_config.lua
function Config.OnDrillingAction()
TriggerServerEvent('myresource:server:addStress', math.random(4, 8))
endNote what Config.OnRobberyStart does in the shipped body. It marks the activity busy on
qb-scoreboard using the bank name, and for the numeric Fleeca IDs it also closes the bank in
qb-banking. If you drop either resource, edit this function rather than leaving a dangling
TriggerEvent.
Server events
| Event | Arguments | Notes |
|---|---|---|
qb-bankrobbery:server:setBankState | bankId | Validates that the bank is not already open and that the player is within 2.5 units, otherwise raises a Lua error naming the source |
qb-bankrobbery:server:setLockerState | bankId, lockerId, state, bool | Validates distance to that locker |
qb-bankrobbery:server:recieveItem | type, bankId, lockerId | Validates distance before granting. Note the spelling, it is recieveItem upstream |
qb-bankrobbery:server:callCops | type, bank, coords | Alarm relay |
qb-bankrobbery:server:SetStationStatus | key, isHit | Power station hit tracking |
qb-bankrobbery:server:removeElectronicKit | none | Consumes the item |
qb-bankrobbery:server:removeBankCard | number | Consumes the item |
thermite:StartServerFire | coords, maxChildren, isGasFire | Fire relay |
thermite:StopFires | none | Fire cleanup |
Server callbacks: qb-bankrobbery:server:isRobberyActive,
qb-bankrobbery:server:GetConfig, and thermite:server:check.
The reward events re-check distance on the server before granting anything, which is the pattern the
rest of your own robbery code should copy. The generic thermite:* event names are not namespaced to
this resource, so check for collisions if you also run a separate thermite script.
Troubleshooting
| Symptom | Likely cause |
|---|---|
| Robbery starts with no police online | The four Config.Minimum*Police values still ship as 0 |
| Police count is always 0 | Nothing fires police:SetCopCount. That event comes from the police job resource |
error lines naming a source in the server console | A reward or state event arrived while the player was further than 2.5 units away. This is the validation working, investigate the source before assuming a bug |
| Rewards never appear | An item name in Config.LockerRewards* is not present in your shared items |
| Doors never lock | Config.DoorlockAction still targets qb-doorlock:server:updateState but you run a different door resource |
| Blackout never happens | Fewer than Config.HitsNeeded stations were hit before the tracker reset |
| Config edits do nothing | The value lives in a different one of the three config files than the one you edited |
Proposed manual smoke test
Not yet executed. On staging:
- Set each
Config.Minimum*Policeabove zero, then confirm a robbery is refused with nobody on duty. - Run one Fleeca branch end to end and confirm lockers grant items that exist in your shared items.
- Confirm
qb-scoreboardflips to busy at the start and back at timeout. - Hit
Config.HitsNeededpower stations and confirm the blackout and its recovery. - Restart the resource mid robbery and confirm doors and bank state recover.