Onex
Onex
Home
Products
Documentation
Changelog
Login with FiveM
  • 👋 Welcome
  • Claim Purchase
  • Translations
    • Weaponmeta
    • Voice Interaction
      Integrations
      Installation
      Configuration
      General
      Currency
      Addons
      Features
      Api
Artifacts Tracker
  1. Onex Scripts
  2. Scripts_guides / Npc Robbery
Ctrl K

NPC ROBBERY — CONFIGURATION#

Configuration for the npc-robbery addon is defined in shared/npc-robbery/default.lua.

The addon lets players rob ambient NPCs at gunpoint using voice commands. Point a weapon at an NPC for 500ms to trigger the robbery. The NPC reacts based on personality traits (brave, cowardly, wealthy, etc.), voice commands progress through demand/threaten phases, and witnesses nearby may react or call the police.

Detection#

Controls how aim detection works.

RobberyConfig.detection.pollInterval#

Typenumber (ms)
Default200

How often the aim detection raycast runs. Lower values are more responsive but slightly more CPU-intensive.

RobberyConfig.detection.raycastDistance#

Typenumber (metres)
Default30.0

Maximum distance the camera raycast checks for a valid NPC target.

RobberyConfig.detection.targetingDuration#

Typenumber (ms)
Default500

How long the player must continuously aim at the same NPC before the robbery triggers.

RobberyConfig.detection.maxDistance#

Typenumber (metres)
Default15.0

Maximum distance between player and NPC for a robbery to be valid. The raycast range is intentionally wider to allow detection; this clamps the actual trigger range.

detection = { pollInterval = 200, raycastDistance = 30.0, targetingDuration = 500, maxDistance = 15.0, }

Weapons#

RobberyConfig.weapons#

Typestring[]

Array of weapon hash names that are considered valid robbery weapons. Only weapons in this list can trigger a robbery. Includes pistols, SMGs, and shotguns by default. Rifles and explosives are intentionally excluded.

Default weapon categories:

  • Pistols (16) — PISTOL, PISTOL_MK2, COMBATPISTOL, APPISTOL, PISTOL50, SNSPISTOL, SNSPISTOL_MK2, HEAVYPISTOL, VINTAGEPISTOL, MARKSMANPISTOL, REVOLVER, REVOLVER_MK2, DOUBLEACTION, CERAMICPISTOL, NAVYREVOLVER, GADGETPISTOL
  • SMGs (7) — MICROSMG, SMG, SMG_MK2, ASSAULTSMG, COMBATPDW, MACHINEPISTOL, MINISMG
  • Shotguns (10) — PUMPSHOTGUN, PUMPSHOTGUN_MK2, SAWNOFFSHOTGUN, ASSAULTSHOTGUN, BULLPUPSHOTGUN, MUSKET, HEAVYSHOTGUN, DBSHOTGUN, AUTOSHOTGUN, COMBATSHOTGUN
weapons = { "WEAPON_PISTOL", "WEAPON_SMG", -- add or remove weapon hashes here }

Excluded Models#

RobberyConfig.excludeModels#

Typestring[]

NPC model hashes that cannot be robbed. Police, military, security, FIB/IAA, and prison guard models are excluded by default (21 models total). Add any model hash string to prevent it from being targeted.

excludeModels = { "s_m_y_cop_01", "s_m_y_swat_01", "s_m_y_armymech_01", -- add custom exclusions here }

Behavior#

Core NPC behavior settings during a robbery.

RobberyConfig.behavior.handsUpDuration#

Typenumber (ms)
Default30000

How long an NPC stays in the hands-up state before the robbery auto-times out (30 seconds).

RobberyConfig.behavior.fearSpeakDelay#

Typenumber (ms)
Default0

Delay before the NPC plays their initial fear TTS phrase after being threatened. 0 plays it immediately.

RobberyConfig.behavior.lookAtPlayerWhileThreatened#

Typeboolean
Defaulttrue

Whether the NPC continuously looks at the player while held at gunpoint.

RobberyConfig.behavior.escapeTimerMin / escapeTimerMax#

Typenumber (ms)
Default8000 / 15000

Random range for how long the NPC waits after the player lowers their gun before attempting to flee. The per-behavior gunpointLoss blocks below override these when applicable.

RobberyConfig.behavior.escapeFleeDistance#

Typenumber (metres)
Default100.0

Distance the NPC flees when escaping.

RobberyConfig.behavior.escapeIfPlayerFarDistance#

Typenumber (metres)
Default10.0

If the player moves further than this distance from the NPC while the robbery is active, the NPC immediately flees.

behavior = { handsUpDuration = 30000, fearSpeakDelay = 0, lookAtPlayerWhileThreatened = true, escapeTimerMin = 8000, escapeTimerMax = 15000, escapeFleeDistance = 100.0, escapeLookAroundChance = 30, escapeIfPlayerFarDistance = 10.0, }

RobberyConfig.behavior.gunpointLoss#

Per-behavior overrides for what happens when the player lowers their gun mid-robbery. Each block overrides the global escape timers and adds behavior-specific reactions.

behavior.gunpointLoss = { passive = { escapeTimerMin = 8000, escapeTimerMax = 15000, }, cowardly = { escapeTimerMin = 12000, -- Too scared to act quickly escapeTimerMax = 20000, }, tough = { reactionDelay = 2000, -- Short window before fight-back decision reactionDelayMax = 4000, fightBackChance = 70, -- High chance to fight when gun is lowered fleeChance = 20, -- If not fighting, may flee aggressively }, wealthy = { escapeTimerMin = 6000, escapeTimerMax = 12000, bribeChance = 40, -- May offer a bribe when gun is lowered negotiateChance = 25, }, }

Cooldowns#

RobberyConfig.cooldowns.perNpc#

Typenumber (ms)
Default300000 (5 minutes)

Per-NPC cooldown. The same NPC cannot be robbed again for 5 minutes after a completed robbery.

RobberyConfig.cooldowns.global#

Typenumber (ms)
Default30000 (30 seconds)

Global cooldown between any two robberies by the same player.

cooldowns = { perNpc = 300000, global = 30000, }

Behaviors#

NPC behavior types are determined by personality traits. Each type has its own config block.

Fallback weights#

When an NPC has no relevant traits, a random behavior is assigned using these weights:

behaviorFallback = { enabled = true, weights = { passive = 55, cowardly = 25, tough = 12, wealthy = 8, } }

Passive (default)#

Default behavior for most NPCs with no special traits. Complies after enough pressure; may attempt to flee after gunpoint is lost.

behaviors.passive = { escapeChance = 60, -- % chance to flee when gun is lowered fightBackChance = 0, -- never fights back }

Tough#

Triggered by traits: brave, hostile, criminal_mindset. Will warn the player, potentially fight back, and escalates as the player re-aims.

behaviors.tough = { enabled = true, fightBackChance = 35, -- % chance to fight back when gun lowered fightBackDelay = 2000, -- ms before fight-back decision warningChance = 60, -- % chance to warn before fighting escalation = { enabled = true, fightBackBonus = 15, -- % added per re-aim cycle maxFightBackChance = 90, -- cap reaimEffectivenessLoss = 20, -- % effectiveness lost per re-aim cycle defianceInterval = 5000, -- ms between defiance outbursts at gunpoint } }

Cowardly#

Triggered by traits: coward, paranoid. May faint, freeze, or panic instead of complying normally.

behaviors.cowardly = { enabled = true, faintChance = 15, -- % chance to pass out freezeChance = 25, -- % chance to freeze up panicChance = 35, -- % chance to panic/scream faintDuration = 15000, -- ms spent fainted before recovering and fleeing }

Wealthy#

Triggered by the economic trait tag. Carries more money and higher-value items; may offer a bribe or negotiate when the gun is lowered (via gunpointLoss.wealthy).

behaviors.wealthy = { enabled = true, -- reward multipliers defined in rewards section(2.5x money, 2.5x items) }

Animations#

RobberyConfig.animations.useVariants#

Typeboolean
Defaulttrue

Use gender-aware animation variants for hands-up and fear poses.

RobberyConfig.animations.kneelingEnabled / kneelingChance#

Typeboolean / number (%)
Defaulttrue / 30

Whether kneeling animations are eligible, and the percentage chance one is chosen over a standing pose.

RobberyConfig.animations.cycleAnimations#

Typeboolean
Defaulttrue

Cycles through the animation pool instead of repeating the same pose.

RobberyConfig.animations.dynamicReactions#

Typeboolean
Defaulttrue

Enables mid-robbery animation shifts (flinch, cower, beg) at random intervals while the player holds the NPC at gunpoint.

RobberyConfig.animations.reactionInterval / reactionChance#

Typenumber (ms) / number (%)
Default4000 / 30

How often a dynamic reaction is checked for and the chance it triggers.

Fidget animations are disabled (fidgetEnabled = false). Upper-body fidget loops caused animation conflicts. Do not enable without testing.

animations = { useVariants = true, kneelingEnabled = true, kneelingChance = 30, cycleAnimations = true, dynamicReactions = true, reactionInterval = 4000, reactionChance = 30, fidgetEnabled = false, -- do not enable }

Feedback / TTS#

Controls NPC speech responses during the robbery.

RobberyConfig.feedback.enabled#

Typeboolean
Defaulttrue

Master toggle for NPC TTS speech during robberies.

RobberyConfig.feedback.maxDistance#

Typenumber (metres)
Default15.0

3D audio hearing range for robbery TTS speech.

RobberyConfig.feedback.responseToggles#

Individual toggles for each response category:

feedback.responseToggles = { fearInitial = true, -- initial fear phrase on robbery trigger compliance = true, -- compliance phrase after demand/threaten toughDefiance = true, -- tough NPC taunts at gunpoint }

RobberyConfig.feedbackTiming#

feedbackTiming = { responseCooldown = 2000, -- ms minimum between TTS responses duplicatePrevention = 10000, -- ms before the same phrase can repeat }

Rewards#

Server-side reward calculation. Framework and inventory are auto-detected.

Money rewards#

rewards.money = { enabled = true, base = { min = 50, max = 200 }, multipliers = { passive = 1.0, cowardly = 0.8, tough = 1.5, wealthy = 2.5, }, emptyChance = 25, -- % chance the NPC has nothing }

Item rewards#

Items in the pool use a name key (not item) matching your inventory system's item names.

rewards.items = { enabled = true, maxItems = 2, pool = { { name = "phone", chance = 25, min = 1, max = 1 }, { name = "wallet", chance = 35, min = 1, max = 1 }, { name = "goldchain", chance = 5, min = 1, max = 1 }, { name = "rolex", chance = 3, min = 1, max = 1 }, }, chanceMultipliers = { passive = 1.0, cowardly = 0.7, tough = 1.2, wealthy = 2.5, }, cooldown = 60000, -- server-side per-player cooldown(ms) }

Wealthy NPCs have an additional exclusive item pool under rewards.items.behaviorItems.wealthy:

behaviorItems = { wealthy = { { name = "rolex", chance = 20, min = 1, max = 1 }, { name = "diamond_ring", chance = 10, min = 1, max = 1 }, }, }

Item names must match your inventory system. For ox_inventory, use the item names defined in your items.lua. For QBCore/ESX, use the item names registered in your shared items table.

Voice Interaction#

RobberyConfig.voiceInteraction.enabled#

Typeboolean
Defaulttrue

Enable voice commands during robberies. When disabled, the player cannot use voice to demand money, threaten, or give permission.

RobberyConfig.voiceInteraction.layerName / layerPriority#

Typestring / number
Default"npc_robbery" / 70

Voice layer identifier and priority. At priority 70 this overrides npc_interact (55), ambient_npc (40), and shops (60).

Voice phases#

The robbery progresses through demand and threaten phases based on voice commands:

voiceInteraction.phases = { demand = { maxRefusals = 2, -- NPC can refuse this many times before forced comply refuseChance = 50, -- % initial chance NPC refuses the demand lieChance = 30, -- % chance NPC lies about having nothing }, threaten = { complyChance = 65, -- % chance NPC complies after being threatened cowerChance = 40, -- % chance NPC plays cower animation during threat }, }

Voice command hint phrases#

Hint phrases shown in the voice bubble per phase:

PhaseExample phrases
demand"give me what you have", "empty your pockets", "give me your money", "hand it over"
threaten"I will shoot you", "don't make me hurt you", "last chance"
hurry"hurry up", "faster", "come on", "now"
permission"yes go", "leave", "get out of here", "you can go"

Witness System#

Detection#

witnesses.detection = { enabled = true, radius = 25.0, -- outer detection range(metres) innerRadius = 10.0, -- guaranteed detection within this range(no LOS required) requireLineOfSight = true, scanInterval = 1000, -- ms between witness scans maxWitnesses = 5, -- performance cap }

Reaction timings#

witnesses.timing = { reactionDelay = { min = 500, max = 2000 }, policeCallDelay = { min = 5000, max = 15000 }, freezeDuration = { min = 3000, max = 8000 }, cooldownPerWitness = 30000, }

Reaction chances by witness type#

TypeFleeFreezeCall PoliceScreamNotes
cowardly70%25%30%80%Default for most NPCs
paranoid40%50%60%40%Nervous types
brave20%—80%10%May confront player (25%)
criminal10%—10%0%Mostly ignores robbery (70%)
neutral50%20%40%50%Mixed reaction

Police dispatch#

witnesses.police = { enabled = true, wantedLevelIncrease = 1, -- stars added per witness police call maxWantedFromWitnesses = 2, -- max stars added by witnesses dispatchDelay = 3000, -- ms after call before wanted level applies -- Custom dispatch event(set event to a name string to enable) onPoliceCall = { type = "client", -- "client" or "server" event = nil, -- nil = disabled; set to event name to enable cb = nil, -- optional function(callbackData) instead of event } }

Set onPoliceCall.event to an event name string to integrate with custom police dispatch systems (e.g. "ps-dispatch:robbery", "cd_dispatch:AddNotification"). The event receives the witness ped's position.

Server Integration#

The server script (addons/npc-robbery/server.lua) auto-detects the active framework and inventory system. No manual configuration is required.

Supported frameworks: QBCore, QBx, ESX

Supported inventories: ox_inventory (preferred), QBCore inventory, ESX inventory

Server events:

EventDirectionDescription
npc-robbery:giveRewardClient → ServerRequest reward after successful robbery
npc-robbery:rewardResultServer → ClientDelivers reward summary (money amount, items, empty flag)

Server-side cooldown: 60 seconds per player (independent of client cooldowns) to prevent exploit via resource restart.

Exports#

Two client-side exports are available for other resources:

-- Check if the addon is initialized and running local active = exports['onex-voiceInteraction']:isRobberyActive() -- Get list of currently threatened NPC entity handles local npcs = exports['onex-voiceInteraction']:getThreatenedNPCs()

Last updated 3 months ago

Quick Links

All DocumentationOur Products