Skip to Content
QBCore docs – powered by Nextra 4
ResourcesQB-Weapons - Weapon Management System

QB-Weapons - Weapon Management System

The qb-weapons resource provides comprehensive weapon management for QBCore servers, featuring weapon attachments, ammunition systems, weapon degradation, and advanced ballistics.

Overview

QB-Weapons enhances the weapon experience with realistic mechanics, customization options, maintenance requirements, and advanced combat features. The system balances realism with gameplay enjoyment.

Key Features

  • Weapon Attachments: Scopes, silencers, grips, and modifications
  • Ammunition System: Different ammo types and effects
  • Weapon Degradation: Durability and maintenance mechanics
  • Ballistics System: Realistic bullet physics and damage
  • Weapon Crafting: Custom weapon creation and modification
  • Serial Numbers: Weapon tracking and identification
  • License System: Legal weapon ownership requirements
  • Advanced Combat: Enhanced shooting mechanics

Installation

Prerequisites

  • QBCore Framework
  • qb-target (for interaction system)
  • qb-menu (for weapon menus)
  • qb-inventory (for weapon storage)

Installation Steps

  1. Download the Resource
cd resources/[qb] git clone https://github.com/qbcore-framework/qb-weapons.git
  1. Database Setup
-- Weapon system tables CREATE TABLE IF NOT EXISTS `weapon_attachments` ( `id` int(11) NOT NULL AUTO_INCREMENT, `weapon_serial` varchar(100) DEFAULT NULL, `attachment_type` varchar(50) DEFAULT NULL, `attachment_component` varchar(100) DEFAULT NULL, `installed_by` varchar(50) DEFAULT NULL, `installed_date` timestamp DEFAULT current_timestamp(), PRIMARY KEY (`id`) ); CREATE TABLE IF NOT EXISTS `weapon_licenses` ( `citizenid` varchar(50) NOT NULL, `license_type` varchar(50) DEFAULT 'basic', `issued_date` timestamp DEFAULT current_timestamp(), `expires_date` timestamp DEFAULT NULL, `status` varchar(50) DEFAULT 'active', `issued_by` varchar(50) DEFAULT NULL, PRIMARY KEY (`citizenid`) );
  1. Add Items to qb-core/shared/items.lua
-- Weapon Attachments ['weapon_scope'] = { ['name'] = 'weapon_scope', ['label'] = 'Weapon Scope', ['weight'] = 200, ['type'] = 'item', ['image'] = 'weapon_scope.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Precision scope for weapons' }, ['weapon_silencer'] = { ['name'] = 'weapon_silencer', ['label'] = 'Weapon Silencer', ['weight'] = 150, ['type'] = 'item', ['image'] = 'weapon_silencer.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Sound suppressor for firearms' }, -- Ammunition Types ['ammo_regular'] = { ['name'] = 'ammo_regular', ['label'] = 'Regular Ammunition', ['weight'] = 5, ['type'] = 'item', ['image'] = 'ammo_regular.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Standard ammunition' }, ['ammo_armor_piercing'] = { ['name'] = 'ammo_armor_piercing', ['label'] = 'Armor Piercing Rounds', ['weight'] = 6, ['type'] = 'item', ['image'] = 'ammo_ap.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'High penetration ammunition' }
  1. Add to server.cfg
ensure qb-weapons

Configuration

Basic Configuration

Config = {} -- General Settings Config.UseTarget = true Config.WeaponDegradation = true Config.RequireLicense = true Config.AttachmentSystem = true -- Weapon Categories Config.WeaponCategories = { ["pistols"] = { label = "Pistols", license_required = "basic", attachments_allowed = {"silencer", "flashlight", "scope"}, max_attachments = 3 }, ["rifles"] = { label = "Rifles", license_required = "rifle", attachments_allowed = {"scope", "silencer", "grip", "bipod"}, max_attachments = 4 }, ["shotguns"] = { label = "Shotguns", license_required = "shotgun", attachments_allowed = {"flashlight", "grip"}, max_attachments = 2 } } -- Attachment Configuration Config.Attachments = { ["silencer"] = { label = "Silencer", component = "COMPONENT_AT_PI_SUPP", effects = { noise_reduction = 0.7, damage_modifier = 0.95, range_modifier = 0.98 }, compatible_weapons = {"weapon_pistol", "weapon_combatpistol", "weapon_carbinerifle"} }, ["scope"] = { label = "Scope", component = "COMPONENT_AT_SCOPE_LARGE", effects = { accuracy_bonus = 0.15, range_bonus = 1.2 }, compatible_weapons = {"weapon_carbinerifle", "weapon_assaultrifle", "weapon_sniperrifle"} }, ["flashlight"] = { label = "Flashlight", component = "COMPONENT_AT_PI_FLSH", effects = { visibility_bonus = true }, compatible_weapons = {"weapon_pistol", "weapon_combatpistol", "weapon_pumpshotgun"} } } -- Degradation System Config.Degradation = { base_degradation_rate = 0.1, -- Per shot repair_kits = { ["weapon_repair_kit"] = { repair_amount = 25, success_rate = 0.9 }, ["advanced_repair_kit"] = { repair_amount = 50, success_rate = 0.95 } }, breakdown_threshold = 10, -- Weapon jams below this durability destruction_threshold = 0 -- Weapon destroyed at 0 durability }

Ammunition System

-- Ammunition Types and Effects Config.AmmunitionTypes = { ["regular"] = { label = "Regular Ammunition", damage_modifier = 1.0, penetration = 0.5, cost = 5 }, ["hollow_point"] = { label = "Hollow Point", damage_modifier = 1.25, penetration = 0.3, cost = 8, license_required = "advanced" }, ["armor_piercing"] = { label = "Armor Piercing", damage_modifier = 0.9, penetration = 0.9, cost = 12, license_required = "advanced" }, ["incendiary"] = { label = "Incendiary Rounds", damage_modifier = 1.1, penetration = 0.6, special_effect = "fire", cost = 15, license_required = "special" } } -- License Types Config.LicenseTypes = { ["basic"] = { label = "Basic Firearms License", cost = 2500, duration = 90, -- days weapons_allowed = {"pistols"}, background_check = true }, ["rifle"] = { label = "Rifle License", cost = 5000, duration = 90, prerequisites = {"basic"}, weapons_allowed = {"pistols", "rifles"}, training_required = true }, ["advanced"] = { label = "Advanced Firearms License", cost = 10000, duration = 60, prerequisites = {"rifle"}, weapons_allowed = {"pistols", "rifles", "shotguns"}, special_ammunition = true } }

API Reference

Client Exports

AttachComponent

Attach a component to a weapon.

local success = exports['qb-weapons']:AttachComponent(weaponHash, componentHash) -- Parameters: -- weaponHash: Weapon hash -- componentHash: Component hash to attach -- Returns: boolean success status

GetWeaponDurability

Get current weapon durability.

local durability = exports['qb-weapons']:GetWeaponDurability(weaponSerial) -- Returns: durability percentage (0-100)

RepairWeapon

Repair a weapon using repair kit.

local success = exports['qb-weapons']:RepairWeapon(weaponSerial, repairKitType) -- Parameters: -- weaponSerial: Weapon serial number -- repairKitType: Type of repair kit to use

Server Exports

CreateWeapon

Create a new weapon with serial number.

local weaponData = exports['qb-weapons']:CreateWeapon(weaponType, quality, craftedBy) -- Parameters: -- weaponType: Type of weapon to create -- quality: Weapon quality (0-100) -- craftedBy: Creator citizen ID

CheckWeaponLicense

Verify player’s weapon license.

local isValid = exports['qb-weapons']:CheckWeaponLicense(source, weaponCategory) -- Parameters: -- source: Player server ID -- weaponCategory: Category of weapon -- Returns: boolean license validity

RegisterWeapon

Register weapon to player.

exports['qb-weapons']:RegisterWeapon(source, weaponSerial, weaponType) -- Parameters: -- source: Player server ID -- weaponSerial: Weapon serial number -- weaponType: Type of weapon

Events

Client Events

-- Weapon degraded RegisterNetEvent('qb-weapons:client:weaponDegraded', function(weaponHash, newDurability) -- Handle weapon degradation end) -- Attachment installed RegisterNetEvent('qb-weapons:client:attachmentInstalled', function(weaponHash, componentHash) -- Handle attachment installation end) -- Weapon jammed RegisterNetEvent('qb-weapons:client:weaponJammed', function(weaponHash) -- Handle weapon jam end)

Server Events

-- Weapon fired RegisterNetEvent('qb-weapons:server:weaponFired', function(weaponHash, ammoType) -- Handle weapon firing end) -- License application RegisterNetEvent('qb-weapons:server:applyLicense', function(licenseType) -- Handle license application end) -- Weapon crafted RegisterNetEvent('qb-weapons:server:weaponCrafted', function(weaponType, components) -- Handle weapon crafting end)

Usage Examples

Weapon Degradation System

-- Client-side degradation tracking local weaponDurability = {} RegisterNetEvent('qb-weapons:client:weaponFired', function() local ped = PlayerPedId() local weapon = GetSelectedPedWeapon(ped) if weapon and weapon ~= GetHashKey("WEAPON_UNARMED") then local weaponSerial = GetWeaponSerial(weapon) if weaponSerial then -- Apply degradation TriggerServerEvent('qb-weapons:server:degradeWeapon', weaponSerial) end end end) -- Server-side degradation processing RegisterNetEvent('qb-weapons:server:degradeWeapon', function(weaponSerial) local src = source local player = QBCore.Functions.GetPlayer(src) if not player then return end -- Get weapon from inventory local weapon = GetWeaponBySerial(player, weaponSerial) if not weapon then return end -- Calculate degradation local currentDurability = weapon.info.durability or 100 local degradationAmount = Config.Degradation.base_degradation_rate -- Apply ammunition type modifiers local ammoType = weapon.info.ammo_type or "regular" local ammoConfig = Config.AmmunitionTypes[ammoType] if ammoConfig and ammoConfig.degradation_modifier then degradationAmount = degradationAmount * ammoConfig.degradation_modifier end local newDurability = math.max(0, currentDurability - degradationAmount) -- Update weapon durability weapon.info.durability = newDurability player.Functions.SetItemInfo(weapon.slot, weapon.info) -- Check for weapon jam or breakdown if newDurability <= Config.Degradation.breakdown_threshold and newDurability > 0 then -- Chance of weapon jam if math.random() < 0.1 then -- 10% chance TriggerClientEvent('qb-weapons:client:weaponJammed', src, weapon.name) end elseif newDurability <= 0 then -- Weapon destroyed player.Functions.RemoveItem(weapon.name, 1, weapon.slot) TriggerClientEvent('QBCore:Notify', src, 'Your weapon broke beyond repair!', 'error') end TriggerClientEvent('qb-weapons:client:updateDurability', src, weaponSerial, newDurability) end)

Attachment System

-- Attachment installation system RegisterNetEvent('qb-weapons:client:installAttachment', function(attachmentType) local ped = PlayerPedId() local weapon = GetSelectedPedWeapon(ped) if weapon == GetHashKey("WEAPON_UNARMED") then QBCore.Functions.Notify("You need to have a weapon equipped", "error") return end -- Check if attachment is compatible local weaponName = GetWeaponNameFromHash(weapon) local attachmentConfig = Config.Attachments[attachmentType] if not attachmentConfig then QBCore.Functions.Notify("Invalid attachment type", "error") return end local isCompatible = false for i = 1, #attachmentConfig.compatible_weapons do if attachmentConfig.compatible_weapons[i] == weaponName then isCompatible = true break end end if not isCompatible then QBCore.Functions.Notify("Attachment not compatible with this weapon", "error") return end -- Check if player has attachment item QBCore.Functions.TriggerCallback('qb-weapons:server:hasAttachment', function(hasAttachment) if hasAttachment then -- Install attachment animation QBCore.Functions.Progressbar("installing_attachment", "Installing " .. attachmentConfig.label .. "...", 10000, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = "amb@world_human_clipboard@male@base", anim = "base", }, {}, {}, function() -- Installation complete TriggerServerEvent('qb-weapons:server:installAttachment', weapon, attachmentType) end) else QBCore.Functions.Notify("You don't have this attachment", "error") end end, attachmentType) end) -- Server-side attachment installation RegisterNetEvent('qb-weapons:server:installAttachment', function(weaponHash, attachmentType) local src = source local player = QBCore.Functions.GetPlayer(src) local attachmentConfig = Config.Attachments[attachmentType] if not player or not attachmentConfig then return end -- Remove attachment item from inventory local attachmentItem = "weapon_" .. attachmentType if player.Functions.RemoveItem(attachmentItem, 1) then -- Apply attachment to weapon local weaponSerial = GetPlayerWeaponSerial(src, weaponHash) if weaponSerial then -- Store attachment in database MySQL.insert('INSERT INTO weapon_attachments (weapon_serial, attachment_type, attachment_component, installed_by) VALUES (?, ?, ?, ?)', { weaponSerial, attachmentType, attachmentConfig.component, player.PlayerData.citizenid }) -- Apply visual component TriggerClientEvent('qb-weapons:client:applyAttachment', src, weaponHash, attachmentConfig.component) TriggerClientEvent('QBCore:Notify', src, attachmentConfig.label .. ' installed successfully!', 'success') end end end)

License System

-- Weapon license application system RegisterNetEvent('qb-weapons:client:applyForLicense', function(licenseType) local licenseConfig = Config.LicenseTypes[licenseType] if not licenseConfig then return end -- Check prerequisites QBCore.Functions.TriggerCallback('qb-weapons:server:checkPrerequisites', function(meetsRequirements, canAfford) if not meetsRequirements then QBCore.Functions.Notify("You don't meet the requirements for this license", "error") return end if not canAfford then QBCore.Functions.Notify("Insufficient funds: $" .. licenseConfig.cost, "error") return end -- Background check process if licenseConfig.background_check then QBCore.Functions.Progressbar("background_check", "Processing background check...", 15000, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = "amb@world_human_clipboard@male@base", anim = "base", }, {}, {}, function() -- Background check complete if math.random() < 0.95 then -- 95% pass rate TriggerServerEvent('qb-weapons:server:issueLicense', licenseType) else QBCore.Functions.Notify("Background check failed", "error") end end) else TriggerServerEvent('qb-weapons:server:issueLicense', licenseType) end end, licenseType) end) -- Server-side license issuance RegisterNetEvent('qb-weapons:server:issueLicense', function(licenseType) local src = source local player = QBCore.Functions.GetPlayer(src) local licenseConfig = Config.LicenseTypes[licenseType] if not player or not licenseConfig then return end -- Process payment if player.Functions.RemoveMoney('bank', licenseConfig.cost, 'weapon-license') then -- Calculate expiration date local expirationDate = os.date("%Y-%m-%d %H:%M:%S", os.time() + (licenseConfig.duration * 24 * 60 * 60)) -- Issue license MySQL.insert('INSERT INTO weapon_licenses (citizenid, license_type, expires_date, issued_by) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE license_type = ?, expires_date = ?', { player.PlayerData.citizenid, licenseType, expirationDate, 'Los Santos Firearms Bureau', licenseType, expirationDate }) -- Give license item player.Functions.AddItem('weapon_license', 1, false, { type = licenseType, expires = expirationDate, holder = player.PlayerData.charinfo.firstname .. " " .. player.PlayerData.charinfo.lastname }) TriggerClientEvent('QBCore:Notify', src, 'Weapon license issued successfully!', 'success') else TriggerClientEvent('QBCore:Notify', src, 'Payment failed', 'error') end end)

Troubleshooting

Common Issues

Attachments Not Working

-- Check weapon compatibility function CheckWeaponCompatibility(weaponHash, attachmentType) local weaponName = GetWeaponNameFromHash(weaponHash) local attachmentConfig = Config.Attachments[attachmentType] if not attachmentConfig then print("Attachment config not found:", attachmentType) return false end for i = 1, #attachmentConfig.compatible_weapons do if attachmentConfig.compatible_weapons[i] == weaponName then return true end end print("Weapon not compatible:", weaponName, "with", attachmentType) return false end

Degradation Issues

  • Verify weapon serial tracking system
  • Check degradation rate calculations
  • Ensure proper inventory integration

License Verification Problems

-- Debug license checking RegisterCommand('checklicense', function() QBCore.Functions.TriggerCallback('qb-weapons:server:getLicense', function(license) if license then print("License type:", license.license_type) print("Expires:", license.expires_date) print("Status:", license.status) else print("No weapon license found") end end) end)

Debug Commands

-- Give weapon attachment /giveattachment [player_id] [attachment_type] -- Repair weapon /repairweapon [player_id] [weapon_serial] -- Check weapon durability /checkdurability [weapon_serial] -- Issue weapon license /issuelicense [player_id] [license_type]

Test weapon mechanics thoroughly to ensure proper balance between realism and gameplay enjoyment.

Last updated on