444 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			444 lines
		
	
	
	
		
			19 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local function IsWeaponBlocked(WeaponName)
 | |
|     local retval = false
 | |
|     for _, name in pairs(Config.DurabilityBlockedWeapons) do
 | |
|         if name == WeaponName then
 | |
|             retval = true
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     return retval
 | |
| end
 | |
| 
 | |
| local function HasAttachment(component, attachments)
 | |
|     local retval = false
 | |
|     local key = nil
 | |
|     for k, v in pairs(attachments) do
 | |
|         if v.component == component then
 | |
|             key = k
 | |
|             retval = true
 | |
|         end
 | |
|     end
 | |
|     return retval, key
 | |
| end
 | |
| 
 | |
| local function GetAttachmentType(attachments)
 | |
|     local attype = nil
 | |
|     for _, v in pairs(attachments) do
 | |
|         attype = v.type
 | |
|     end
 | |
|     return attype
 | |
| end
 | |
| 
 | |
| function Split(s, delimiter)
 | |
|     result = {};
 | |
|     if not s then return Wait(100) end
 | |
|     for match in (s .. delimiter):gmatch('(.-)' .. delimiter) do
 | |
|         table.insert(result, match);
 | |
|     end
 | |
|     return result;
 | |
| end
 | |
| 
 | |
| RegisterNetEvent('weapons:reloadWeapon', function(ammoType)
 | |
|     local src = source
 | |
|     local player = GetPlayerFromId(src)
 | |
|     local items = GetItems(player)
 | |
|     if not ammoType then
 | |
|         Error('Your weapons.lua is broken! AMMO_TYPE is not found. Please follow our docs and use our qb-core if it needs!')
 | |
|         return
 | |
|     end
 | |
|     ammoType = type(ammoType) == 'table' and ammoType or { ammoType }
 | |
|     local ammoItems = {}
 | |
|     for k, v in pairs(ammoType) do
 | |
|         local item = table.find(Config.AmmoItems, function(item) return item.type == v end)
 | |
|         if item then
 | |
|             ammoItems[#ammoItems + 1] = item.item
 | |
|         end
 | |
|     end
 | |
|     local item
 | |
|     for k, v in pairs(items) do
 | |
|         if v.name == table.find(Config.AmmoItems, function(item) return item.isForEveryWeapon end).item then
 | |
|             item = v
 | |
|             break
 | |
|         end
 | |
|         if table.includes(ammoItems, v.name) then
 | |
|             item = v
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     if not item then
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_AMMO'), 'error')
 | |
|         return
 | |
|     end
 | |
|     lib.callback.await('weapons:addAmmo', src, item)
 | |
| end)
 | |
| 
 | |
| lib.callback.register('weapons:GetWeaponAmmoItem', function(source, ammoType, checkMaster)
 | |
|     local player = GetPlayerFromId(source)
 | |
|     local items = GetItems(player)
 | |
|     if not ammoType then
 | |
|         Error('Your weapons.lua is broken! AMMO_TYPE is not found. Please follow our docs and use our qb-core if it needs!')
 | |
|         return
 | |
|     end
 | |
|     ammoType = type(ammoType) == 'table' and ammoType or { ammoType }
 | |
|     local ammoItems = {}
 | |
|     for k, v in pairs(ammoType) do
 | |
|         local item = table.find(Config.AmmoItems, function(item) return item.type == v end)
 | |
|         if item then
 | |
|             ammoItems[#ammoItems + 1] = item.item
 | |
|         end
 | |
|     end
 | |
|     Debug('ammoType', ammoType)
 | |
|     for k, v in pairs(items) do
 | |
|         if checkMaster and v.name == table.find(Config.AmmoItems, function(item) return item.isForEveryWeapon end).item then
 | |
|             return v
 | |
|         end
 | |
|         if table.includes(ammoItems, v.name) then
 | |
|             return v
 | |
|         end
 | |
|     end
 | |
|     return false
 | |
| end)
 | |
| 
 | |
| RegisterServerCallback('weapon:server:GetWeaponAmmo', function(source, cb, WeaponData)
 | |
|     local retval = 0
 | |
|     if WeaponData then
 | |
|         local ItemData = GetItemBySlot(source, WeaponData.slot)
 | |
|         if ItemData then
 | |
|             retval = ItemData.info.ammo and ItemData.info.ammo or 0
 | |
|         end
 | |
|     end
 | |
|     cb(retval, WeaponData.name)
 | |
| end)
 | |
| 
 | |
| RegisterServerCallback('weapons:server:RemoveAttachment', function(source, cb, AttachmentData, ItemData)
 | |
|     local src = source
 | |
|     local Inventory = GetItems(GetPlayerFromId(src))
 | |
|     Debug('Attachmentdata', AttachmentData)
 | |
|     local AttachmentComponent = Config.WeaponAttachments[ItemData.name:upper()][AttachmentData.attachment]
 | |
|     if Inventory[ItemData.slot] then
 | |
|         if Inventory[ItemData.slot].info.attachments and next(Inventory[ItemData.slot].info.attachments) then
 | |
|             Debug('AttachmentComponent:', AttachmentComponent)
 | |
|             local HasAttach, key = HasAttachment(AttachmentComponent.component, Inventory[ItemData.slot].info.attachments)
 | |
|             if HasAttach then
 | |
|                 if Inventory[ItemData.slot].info.tinturl and AttachmentComponent.item == 'weapontint_url' then
 | |
|                     local info = {}
 | |
|                     info.urltint = tostring(Inventory[ItemData.slot].info.tinturl)
 | |
|                     AddItem(src, 'weapontint_url', 1, false, info)
 | |
|                 end
 | |
|                 if AttachmentComponent.item ~= 'weapontint_url' then
 | |
|                     AddItem(src, AttachmentComponent.item, 1)
 | |
|                 end
 | |
|                 table.remove(Inventory[ItemData.slot].info.attachments, key)
 | |
|                 SetItemMetadata(src, ItemData.slot, Inventory[ItemData.slot].info)
 | |
|                 TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_ATTACHMENT_REMOVED') .. ' ' .. ItemList[AttachmentComponent.item].label, 'success')
 | |
|                 cb(Inventory[ItemData.slot].info.attachments)
 | |
|                 if Config.RemoveTintAfterRemoving then
 | |
|                     if AttachmentData.tint or AttachmentData.tinturl then
 | |
|                         Debug('An Tint was permanently removed')
 | |
|                         RemoveItem(src, AttachmentData.item, 1)
 | |
|                     end
 | |
|                 end
 | |
|                 Wait(200)
 | |
|                 TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src, Inventory[ItemData.slot], false, AttachmentComponent.component)
 | |
|                 TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src)
 | |
|             else
 | |
|                 cb(false)
 | |
|             end
 | |
|         else
 | |
|             cb(false)
 | |
|         end
 | |
|     else
 | |
|         cb(false)
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterServerCallback('weapons:server:RepairWeapon', function(source, cb, RepairPoint, data)
 | |
|     local src = source
 | |
|     local Player = GetPlayerFromId(src)
 | |
|     local identifier = GetPlayerIdentifier(src)
 | |
|     local minute = 60 * 1000
 | |
|     local Timeout = math.random(5 * minute, 10 * minute)
 | |
|     local WeaponData = WeaponList[GetHashKey(data.name)]
 | |
|     local items = GetItems(Player)
 | |
| 
 | |
|     if items[data.slot] then
 | |
|         if items[data.slot].info.quality then
 | |
|             if items[data.slot].info.quality ~= 100 then
 | |
|                 local cash = GetAccountMoney(src, 'money')
 | |
|                 if cash >= Config.WeaponRepairCosts[WeaponData.weapontype] then
 | |
|                     items[data.slot].info.quality = 100
 | |
|                     SetItemMetadata(src, data.slot, items[data.slot].info)
 | |
|                     TriggerClientEvent(Config.InventoryPrefix .. ':client:CheckWeapon', src, data.name)
 | |
|                     TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_TEXT_REPAIR_REPAIRED'), 'error')
 | |
|                     RemoveAccountMoney(src, 'money', Config.WeaponRepairCosts[WeaponData.weapontype])
 | |
|                     cb(true)
 | |
|                 else
 | |
|                     TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_MONEY'), 'error')
 | |
|                     cb(false)
 | |
|                 end
 | |
|             else
 | |
|                 TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_BROKEN'), 'error')
 | |
|                 cb(false)
 | |
|             end
 | |
|         else
 | |
|             TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_BROKEN'), 'error')
 | |
|             cb(false)
 | |
|         end
 | |
|     else
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NO_WEAPON'), 'error')
 | |
|         TriggerClientEvent('weapons:client:SetCurrentWeapon', src, {}, false)
 | |
|         cb(false)
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterServerCallback('prison:server:checkThrowable', function(source, cb, weapon)
 | |
|     local Player = GetPlayerFromId(source)
 | |
| 
 | |
|     if not Player then return cb(false) end
 | |
|     local throwable = false
 | |
|     for _, v in pairs(Config.Throwables) do
 | |
|         if WeaponList[weapon].name == 'weapon_' .. v then
 | |
|             RemoveItem(source, v, 1)
 | |
|             throwable = true
 | |
|             break
 | |
|         end
 | |
|     end
 | |
|     cb(throwable)
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('weapons:server:UpdateWeaponAmmo', function(CurrentWeaponData, amount)
 | |
|     local src = source
 | |
|     local Player = GetPlayerFromId(src)
 | |
|     local items = GetItems(Player)
 | |
|     amount = tonumber(amount)
 | |
|     if CurrentWeaponData then
 | |
|         if items[CurrentWeaponData.slot] then
 | |
|             items[CurrentWeaponData.slot].info.ammo = amount
 | |
|             local success = SetItemMetadata(src, CurrentWeaponData.slot, items[CurrentWeaponData.slot].info)
 | |
|             Debug('weapons:server:UpdateWeaponAmmo', success)
 | |
|         else
 | |
|             Debug('CurrentWeaponData is nil')
 | |
|         end
 | |
|     else
 | |
|         Debug('CurrentWeaponData is nil')
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('weapons:server:TakeBackWeapon', function(k)
 | |
|     local src = source
 | |
|     local itemdata = Config.WeaponRepairPoints[k].RepairingData.WeaponData
 | |
|     itemdata.info.quality = 100
 | |
|     AddItem(src, itemdata.name, 1, nil, itemdata.info)
 | |
|     Config.WeaponRepairPoints[k].IsRepairing = false
 | |
|     Config.WeaponRepairPoints[k].RepairingData = {}
 | |
|     TriggerClientEvent('weapons:client:SyncRepairShops', -1, Config.WeaponRepairPoints[k], k)
 | |
| end)
 | |
| 
 | |
| ---@param data ServerProgressBar
 | |
| function ProgressBarSync(src, data)
 | |
|     return lib.callback.await('inventory:progressBarSync', src, data)
 | |
| end
 | |
| 
 | |
| CreateUsableItem('weapon_repairkit', function(source, item)
 | |
|     local src = source
 | |
|     local Player = GetPlayerFromId(src)
 | |
|     local items = GetItems(Player)
 | |
|     local currentWeapon = lib.callback.await('weapons:client:GetCurrentWeapon', src)
 | |
|     if not currentWeapon then
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_REPAIR_HANDS'), 'error')
 | |
|         return
 | |
|     end
 | |
|     if currentWeapon?.info?.quality == 100 then
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_REPAIR_ERROR'), 'error')
 | |
|         return
 | |
|     end
 | |
|     local success = ProgressBarSync(src, {
 | |
|         label = Lang('INVENTORY_PROGRESS_REPAIR'),
 | |
|         name = 'weapon_repairkit',
 | |
|         duration = 1000,
 | |
|         useWhileDead = false,
 | |
|         canCancel = true,
 | |
|         disableControls = { move = true, car = true, mouse = false, combat = true },
 | |
|     })
 | |
|     if success then
 | |
|         RemoveItem(src, item.name, 1, item.slot)
 | |
|         local item = items[currentWeapon.slot]
 | |
|         if item.name == currentWeapon.name then
 | |
|             local quality = item.info.quality
 | |
|             item.info.quality = quality + Config.WeaponRepairItemAddition
 | |
|             if item.info.quality > 100 then
 | |
|                 item.info.quality = 100
 | |
|             end
 | |
|             SetItemMetadata(src, currentWeapon.slot, item.info)
 | |
|             TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_TEXT_REPAIR_REPAIRED'), 'success')
 | |
|         else
 | |
|             Error('Item name and current weapon name do not match. probably player change the slot after use the weapon.')
 | |
|         end
 | |
|         Debug('current weapon', currentWeapon)
 | |
|     end
 | |
| end)
 | |
| RegisterNetEvent('weapons:server:SetWeaponQuality', function(data, hp)
 | |
|     local src = source
 | |
|     local Player = GetPlayerFromId(src)
 | |
|     local items = GetItems(Player)
 | |
|     local WeaponSlot = items[data.slot]
 | |
|     WeaponSlot.info.quality = hp
 | |
|     SetItemMetadata(src, data.slot, WeaponSlot.info)
 | |
| end)
 | |
| 
 | |
| exports('GetCurrentWeapon', function(source)
 | |
|     local currentWeapon = lib.callback.await('weapons:client:GetCurrentWeapon', source)
 | |
|     return currentWeapon
 | |
| end)
 | |
| 
 | |
| -- RegisterCommand('currentweapon', function(source)
 | |
| --     print('currentWeapon', json.encode(exports['qs-inventory']:GetCurrentWeapon(source)))
 | |
| -- end, false)
 | |
| 
 | |
| RegisterNetEvent('weapons:server:UpdateWeaponQuality', function(data, RepeatAmount, ammo)
 | |
|     local src = source
 | |
|     local Player = GetPlayerFromId(src)
 | |
|     local items = GetItems(Player)
 | |
|     local WeaponData = WeaponList[GetHashKey(data.name)]
 | |
|     local WeaponSlot = items[data.slot]
 | |
|     local DecreaseAmount = Config.DurabilityMultiplier[data.name] or 0.15
 | |
|     if WeaponSlot then
 | |
|         if not IsWeaponBlocked(WeaponData.name) then
 | |
|             if WeaponSlot.info.quality then
 | |
|                 for _ = 1, RepeatAmount, 1 do
 | |
|                     if data.name == 'weapon_petrolcan' then
 | |
|                         local customQuality = ammo * 100
 | |
|                         if customQuality >= 1 then
 | |
|                             WeaponSlot.info.quality = customQuality / 4500
 | |
|                         else
 | |
|                             WeaponSlot.info.quality = 0
 | |
|                             WeaponSlot.info.ammo = 0
 | |
|                             TriggerClientEvent(Config.InventoryPrefix .. ':client:UseWeapon', src, data, false)
 | |
|                             TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NEED_REPAIR'), 'inform')
 | |
|                         end
 | |
|                     end
 | |
|                     if WeaponSlot.info.quality - DecreaseAmount > 0 then
 | |
|                         WeaponSlot.info.quality = WeaponSlot.info.quality - DecreaseAmount
 | |
|                     else
 | |
|                         WeaponSlot.info.quality = 0
 | |
|                         TriggerClientEvent(Config.InventoryPrefix .. ':client:UseWeapon', src, data, false)
 | |
|                         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NEED_REPAIR'), 'inform')
 | |
|                         break
 | |
|                     end
 | |
|                 end
 | |
|             else
 | |
|                 WeaponSlot.info.quality = 100
 | |
|                 for _ = 1, RepeatAmount, 1 do
 | |
|                     if WeaponSlot.info.quality - DecreaseAmount > 0 then
 | |
|                         WeaponSlot.info.quality = WeaponSlot.info.quality - DecreaseAmount
 | |
|                     else
 | |
|                         WeaponSlot.info.quality = 0
 | |
|                         TriggerClientEvent(Config.InventoryPrefix .. ':client:UseWeapon', src, data, false)
 | |
|                         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_NEED_REPAIR'), 'inform')
 | |
|                         break
 | |
|                     end
 | |
|                 end
 | |
|             end
 | |
|         end
 | |
|     end
 | |
|     SetItemMetadata(src, data.slot, WeaponSlot.info)
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('weapons:server:EquipAttachment', function(ItemData, CurrentWeaponData, AttachmentData, sendData)
 | |
|     local src = source
 | |
|     local Player = GetPlayerFromId(src)
 | |
|     local Inventory = GetItems(Player)
 | |
|     local GiveBackItem = nil
 | |
|     local tint = 'none'
 | |
|     if ItemData?.info?.urltint ~= nil then
 | |
|         tint = tostring(ItemData.info.urltint)
 | |
|     end
 | |
|     local attachmentInfo = table.find(Config.WeaponAttachmentItems, function(attachment)
 | |
|         return attachment.item == AttachmentData.item
 | |
|     end)
 | |
|     if not attachmentInfo then
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_ATTACHMENT_NOT_FOUND'), 'error')
 | |
|         return
 | |
|     end
 | |
|     AttachmentData.type = attachmentInfo.type
 | |
|     Debug('weapons:server:EquipAttachment', AttachmentData)
 | |
|     if Inventory[CurrentWeaponData.slot] then
 | |
|         if Inventory[CurrentWeaponData.slot].info.attachments and next(Inventory[CurrentWeaponData.slot].info.attachments) then
 | |
|             local currenttype = GetAttachmentType(Inventory[CurrentWeaponData.slot].info.attachments)
 | |
|             local HasAttach, key = HasAttachment(AttachmentData.component, Inventory[CurrentWeaponData.slot].info.attachments)
 | |
|             if not HasAttach then
 | |
|                 if AttachmentData.type ~= nil and currenttype == AttachmentData.type then
 | |
|                     for _, v in pairs(Inventory[CurrentWeaponData.slot].info.attachments) do
 | |
|                         if v.type and v.type == currenttype then
 | |
|                             GiveBackItem = tostring(v.item):lower()
 | |
|                             table.remove(Inventory[CurrentWeaponData.slot].info.attachments, key)
 | |
|                         end
 | |
|                     end
 | |
|                 end
 | |
|                 Inventory[CurrentWeaponData.slot].info.attachments[#Inventory[CurrentWeaponData.slot].info.attachments + 1] = {
 | |
|                     component = AttachmentData.component,
 | |
|                     label = ItemList[AttachmentData.item].label,
 | |
|                     item = AttachmentData.item,
 | |
|                     type = AttachmentData.type,
 | |
|                     tint = AttachmentData.tint,
 | |
|                     urltint = tint
 | |
|                 }
 | |
|                 Inventory[CurrentWeaponData.slot].info.tinturl = tint
 | |
|                 TriggerClientEvent('addAttachment', src, AttachmentData.component, tint)
 | |
|                 SetItemMetadata(src, CurrentWeaponData.slot, Inventory[CurrentWeaponData.slot].info)
 | |
|                 RemoveItem(src, ItemData.name, 1, ItemData.slot)
 | |
|                 Debug('Attachment used: [' .. ItemData.name .. '], slot: [' .. json.encode(ItemData.slot) .. ']')
 | |
|             else
 | |
|                 TriggerClientEvent(Config.InventoryPrefix .. ':client:sendTextMessage', src, Lang('INVENTORY_NOTIFICATION_ATTACHMENT_ALREADY') .. ' ' .. ItemList[AttachmentData.item].label .. ' ' .. Lang('INVENTORY_NOTIFICATION_ATTACHMENT_ON_YOUR'), 'error')
 | |
|             end
 | |
|         else
 | |
|             Inventory[CurrentWeaponData.slot].info.attachments = {}
 | |
|             Inventory[CurrentWeaponData.slot].info.attachments[#Inventory[CurrentWeaponData.slot].info.attachments + 1] = {
 | |
|                 component = AttachmentData.component,
 | |
|                 label = ItemList[AttachmentData.item].label,
 | |
|                 item = AttachmentData.item,
 | |
|                 type = AttachmentData.type,
 | |
|                 tint = AttachmentData.tint,
 | |
|                 urltint = tint
 | |
|             }
 | |
|             Inventory[CurrentWeaponData.slot].info.tinturl = tint
 | |
|             TriggerClientEvent('addAttachment', src, AttachmentData.component, tint)
 | |
|             SetItemMetadata(src, CurrentWeaponData.slot, Inventory[CurrentWeaponData.slot].info)
 | |
|             RemoveItem(src, ItemData.name, 1, ItemData.slot)
 | |
|             Debug('Attachment used: [' .. ItemData.name .. '], slot: [' .. json.encode(ItemData.slot) .. ']')
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     if GiveBackItem then
 | |
|         AddItem(src, GiveBackItem, 1)
 | |
|         Wait(100)
 | |
|     end
 | |
| 
 | |
|     if sendData then
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src, Inventory[CurrentWeaponData.slot], AttachmentData.component)
 | |
|         Wait(100)
 | |
|         TriggerClientEvent(Config.InventoryPrefix .. ':RefreshWeaponAttachments', src)
 | |
|     end
 | |
| end)
 | |
| 
 | |
| RegisterNetEvent('weapons:server:removeWeaponAmmoItem', function(item)
 | |
|     local Player = GetPlayerFromId(source)
 | |
| 
 | |
|     if not Player or type(item) ~= 'table' or not item.name or not item.slot then return end
 | |
| 
 | |
|     RemoveItem(source, item.name, 1, item.slot)
 | |
| end)
 | |
| 
 | |
| RegisterServerEvent('weapons:server:AddWeaponAmmo')
 | |
| AddEventHandler('weapons:server:AddWeaponAmmo', function(CurrentWeaponData, amount)
 | |
|     local src = source
 | |
|     local amount = tonumber(amount)
 | |
|     local inventory = Inventories[src]
 | |
| 
 | |
|     if CurrentWeaponData ~= nil then
 | |
|         if inventory[CurrentWeaponData.slot] ~= nil then
 | |
|             inventory[CurrentWeaponData.slot].info.ammo = amount
 | |
|         end
 | |
|         SetInventory(src, inventory)
 | |
|     end
 | |
| end)
 | 
