The RSG Weapons system (rsg-weapons) manages weapon durability, damage, repairs, and ammunition in the RSG Framework. It works seamlessly with rsg-inventory to provide a realistic weapon experience.Version: 2.1.4
rsg-weapons is tightly integrated with rsg-inventory. Weapons are stored as inventory items with type 'weapon'.
Weapons are stored in the inventory system with special properties:
Copy
{ name = 'weapon_revolver_cattleman', label = 'Cattleman Revolver', amount = 1, type = 'weapon', -- Must be 'weapon' type slot = 1, weight = 2000, unique = true, -- Each weapon takes its own slot useable = false, image = 'weapon_revolver_cattleman.png', info = { serie = 'ABC12XYZ34DEF56', -- Unique serial number quality = 100, -- Weapon condition (0-100) ammo = 6 -- Current ammo loaded }}
Every weapon gets a unique serial number automatically when added to inventory. This allows tracking and differentiating between identical weapons.
-- Triggered automatically when player uses repair kitRegisterNetEvent('rsg-weapons:server:repairweapon', function(serie) local src = source local Player = RSGCore.Functions.GetPlayer(src) for _, v in pairs(Player.PlayerData.items) do if v.type == 'weapon' and v.info.serie == serie then -- Restore weapon to 100% Player.PlayerData.items[v.slot].info.quality = 100 break end end Player.Functions.SetInventory(Player.PlayerData.items)end)
RSGCore.Functions.CreateCallback('rsg-weapons:server:getweaponinfo', function(source, cb, weaponserial) local weaponinfo = MySQL.query.await('SELECT * FROM player_weapons WHERE serial=@weaponserial', { ['@weaponserial'] = weaponserial }) if weaponinfo[1] == nil then return end cb(weaponinfo)end)
Usage:
Copy
-- CLIENT SIDERSGCore.Functions.TriggerCallback('rsg-weapons:server:getweaponinfo', function(weaponData) if weaponData then print('Weapon Serial: '.. weaponData[1].serial) print('Weapon Owner: '.. weaponData[1].citizenid) endend, weaponSerial)
-- Command: /infinityammo (admin only)RegisterNetEvent('rsg-weapons:requestToggle', function() local src = source if RSGCore.Functions.HasPermission(src, 'admin') then TriggerClientEvent('rsg-weapons:toggle', src) else TriggerClientEvent('ox_lib:notify', src, { title = 'Infinity Ammo', description = 'You do not have permission to use this command.', type = 'error' }) endend)
When removing weapons, use the weapon’s serial to target specific weapons:
Copy
-- SERVER SIDElocal Player = RSGCore.Functions.GetPlayer(source)local weapon = nilfor _, item in pairs(Player.PlayerData.items) do if item.type == 'weapon' and item.info.serie == targetSerial then weapon = item break endendif weapon then exports['rsg-inventory']:RemoveItem(source, weapon.name, 1, weapon.slot, 'confiscated')end
-- SERVER SIDERegisterNetEvent('gunstore:server:purchaseWeapon', function(weaponName, price) local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end -- Check money if Player.Functions.GetMoney('cash') < price then lib.notify({ description = 'Not enough money', type = 'error' }) return end -- Check inventory space local canAdd = exports['rsg-inventory']:CanAddItem(src, weaponName, 1) if not canAdd then lib.notify({ description = 'Cannot carry more weapons', type = 'error' }) return end -- Process purchase if Player.Functions.RemoveMoney('cash', price, 'weapon-purchase') then local weaponInfo = { quality = 100, ammo = 0 -- Serial is auto-generated } exports['rsg-inventory']:AddItem(src, weaponName, 1, nil, weaponInfo, 'gunstore-purchase') lib.notify({ description = 'Weapon purchased!', type = 'success' }) endend)
-- SERVER SIDERegisterNetEvent('police:server:confiscateWeapons', function(targetId) local src = source local Player = RSGCore.Functions.GetPlayer(src) local Target = RSGCore.Functions.GetPlayer(targetId) if not Player or not Target then return end -- Check if law enforcement if Player.PlayerData.job.type ~= 'leo' then lib.notify({ description = 'You are not law enforcement', type = 'error' }) return end -- Get all weapons from target local weapons = {} for _, item in pairs(Target.PlayerData.items) do if item.type == 'weapon' then weapons[#weapons + 1] = item end end if #weapons == 0 then lib.notify({ description = 'No weapons found', type = 'error' }) return end -- Remove all weapons for i = 1, #weapons do exports['rsg-inventory']:RemoveItem(targetId, weapons[i].name, 1, weapons[i].slot, 'confiscated-by-law') end -- Notify TriggerClientEvent('ox_lib:notify', targetId, { description = 'Your weapons have been confiscated', type = 'error' }) lib.notify({ description = 'Confiscated '.. #weapons ..' weapons', type = 'success' }) -- Log TriggerEvent('rsg-log:server:CreateLog', 'weapons', 'Weapons Confiscated', 'red', string.format('**%s** confiscated %d weapons from **%s**', GetPlayerName(src), #weapons, GetPlayerName(targetId)))end)
-- SERVER SIDERegisterNetEvent('weapons:server:checkDurability', function() local src = source local Player = RSGCore.Functions.GetPlayer(src) if not Player then return end local weapons = {} for _, item in pairs(Player.PlayerData.items) do if item.type == 'weapon' then weapons[#weapons + 1] = { name = item.label, quality = item.info.quality, serial = item.info.serie } end end if #weapons == 0 then lib.notify({ description = 'You have no weapons', type = 'error' }) return end -- Send to client for display TriggerClientEvent('weapons:client:showDurability', src, weapons)end)
Copy
-- CLIENT SIDERegisterNetEvent('weapons:client:showDurability', function(weapons) local options = {} for i = 1, #weapons do local weapon = weapons[i] local condition = 'Excellent' if weapon.quality < 75 then condition = 'Good' end if weapon.quality < 50 then condition = 'Poor' end if weapon.quality < 25 then condition = 'Very Poor' end if weapon.quality <= 0 then condition = 'Broken' end options[#options + 1] = { title = weapon.name, description = 'Condition: '.. condition ..' ('.. math.floor(weapon.quality) ..'%)', metadata = { { label = 'Serial', value = weapon.serial }, { label = 'Quality', value = math.floor(weapon.quality) ..'%' } }, disabled = true } end lib.registerContext({ id = 'weapon_durability', title = 'Weapon Condition', options = options }) lib.showContext('weapon_durability')end)