414 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			414 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local PlayerData = GetPlayerData()
 | 
						|
local CanShoot, MultiplierAmount = true, 0
 | 
						|
CurrentWeaponData = {}
 | 
						|
 | 
						|
exports('GetCurrentWeapon', function()
 | 
						|
    return CurrentWeaponData
 | 
						|
end)
 | 
						|
 | 
						|
lib.callback.register('weapons:client:GetCurrentWeapon', function()
 | 
						|
    return CurrentWeaponData
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while not Config.WeaponsOnVehicle do
 | 
						|
        Wait(250)
 | 
						|
        local playerPed = PlayerPedId()
 | 
						|
 | 
						|
        if IsPedInAnyVehicle(playerPed, false) then
 | 
						|
            local playerVeh = GetVehiclePedIsIn(playerPed, false)
 | 
						|
            TriggerEvent('weapons:ResetHolster')
 | 
						|
            SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true)
 | 
						|
            RemoveAllPedWeapons(playerPed, true)
 | 
						|
            currentWeapon = nil
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:SyncRepairShops', function(NewData, key)
 | 
						|
    Config.WeaponRepairPoints[key].IsRepairing = NewData.IsRepairing
 | 
						|
    Config.WeaponRepairPoints[key].RepairingData = NewData.RepairingData
 | 
						|
end)
 | 
						|
 | 
						|
FiringWeapon = false
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        local ped = PlayerPedId()
 | 
						|
        if IsPedArmed(ped, 7) == 1 and not inInventory then
 | 
						|
            if IsControlJustPressed(0, 24) or IsDisabledControlJustPressed(0, 24) then
 | 
						|
                FiringWeapon = true
 | 
						|
            elseif IsControlJustReleased(0, 24) or IsDisabledControlJustReleased(0, 24) and not inInventory then
 | 
						|
                FiringWeapon = false
 | 
						|
            end
 | 
						|
        end
 | 
						|
        Wait(0)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        local ped = PlayerPedId()
 | 
						|
        local weapon = GetSelectedPedWeapon(ped)
 | 
						|
        if WeaponList[weapon] and WeaponList[weapon]['name'] == 'weapon_unarmed' and FiringWeapon then
 | 
						|
            FiringWeapon = false
 | 
						|
        end
 | 
						|
        Wait(500)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
---@return AttachmentItem?
 | 
						|
local function componentIsTint(component)
 | 
						|
    local tints = GetConfigTints()
 | 
						|
    local attachment = table.find(tints, function(tint)
 | 
						|
        return tint.attachment == component
 | 
						|
    end)
 | 
						|
    return attachment
 | 
						|
end
 | 
						|
 | 
						|
RegisterNetEvent('addAttachment', function(component, urltint)
 | 
						|
    local ped = PlayerPedId()
 | 
						|
    local weapon = GetSelectedPedWeapon(ped)
 | 
						|
    local WeaponData = WeaponList[weapon]
 | 
						|
    local tintData = componentIsTint(component)
 | 
						|
    if tintData then
 | 
						|
        if tintData.isUrlTint then
 | 
						|
            for i = 1, #Config.WeaponTints do
 | 
						|
                if tostring(weapon) == Config.WeaponTints[i].hash then
 | 
						|
                    local txd = CreateRuntimeTxd(Config.WeaponTints[i].name)
 | 
						|
                    local duiObj = CreateDui(urltint, 250, 250)
 | 
						|
                    local dui = GetDuiHandle(duiObj)
 | 
						|
                    CreateRuntimeTextureFromDuiHandle(txd, 'skin', dui)
 | 
						|
                    while not IsDuiAvailable(duiObj) do Wait(150) end
 | 
						|
                    AddReplaceTexture(Config.WeaponTints[i].ytd, Config.WeaponTints[i].texture, Config.WeaponTints[i].name, 'skin')
 | 
						|
                    break
 | 
						|
                end
 | 
						|
            end
 | 
						|
        else
 | 
						|
            SetPedWeaponTintIndex(ped, weapon, tintData.tint)
 | 
						|
        end
 | 
						|
        return
 | 
						|
    end
 | 
						|
    GiveWeaponComponentToPed(ped, GetHashKey(WeaponData.name), GetHashKey(component))
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:SetCurrentWeapon', function(data, bool)
 | 
						|
    if data ~= false then
 | 
						|
        CurrentWeaponData = data
 | 
						|
    else
 | 
						|
        CurrentWeaponData = {}
 | 
						|
    end
 | 
						|
    CanShoot = bool
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:SetWeaponQuality', function(amount)
 | 
						|
    if CurrentWeaponData and next(CurrentWeaponData) then
 | 
						|
        TriggerServerEvent('weapons:server:SetWeaponQuality', CurrentWeaponData, amount)
 | 
						|
        TriggerEvent('weapons:client:SetCurrentWeapon', CurrentWeaponData, true)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:masterAmmo', function(amount, itemData)
 | 
						|
    local ped = PlayerPedId()
 | 
						|
    local weapon = GetSelectedPedWeapon(ped)
 | 
						|
    if CurrentWeaponData and WeaponList[weapon] and WeaponList[weapon]['name'] ~= 'weapon_unarmed' then
 | 
						|
        local weaponAmmoType = WeaponList[weapon]['ammotype']
 | 
						|
        if not weaponAmmoType then
 | 
						|
            SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_AMMO'), 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
        TriggerEvent('weapons:client:AddAmmo', weaponAmmoType, amount, itemData, true)
 | 
						|
    else
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_WEAPON'), 'error')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
lib.callback.register('weapons:addAmmo', function(itemData)
 | 
						|
    local ped = cache.ped
 | 
						|
    if IsPedReloading(ped) then
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local weapon = GetSelectedPedWeapon(ped)
 | 
						|
    if not CurrentWeaponData or not WeaponList[weapon] or WeaponList[weapon]['name'] == 'weapon_unarmed' then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_WEAPON'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local total = GetAmmoInPedWeapon(ped, weapon)
 | 
						|
    local retval = GetMaxAmmoInClip(ped, weapon, 1)
 | 
						|
    local _, ammoclip = GetAmmoInClip(ped, weapon)
 | 
						|
    local _, maxammo = GetMaxAmmo(ped, weapon)
 | 
						|
    if IsPedInAnyVehicle(ped, false) and Config.ForceToOnlyOneMagazine then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_VEHICLE_ITEMS'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    if Config.ForceToOnlyOneMagazine and ammoclip > 0 then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_MAGAZINE_LIMIT'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    if not retval then
 | 
						|
        return
 | 
						|
    end
 | 
						|
    retval = tonumber(retval)
 | 
						|
 | 
						|
    if maxammo ~= total then
 | 
						|
        TriggerServerCallback('weapon:server:GetWeaponAmmo', function(ammo)
 | 
						|
            if ammo then
 | 
						|
                SetAmmoInClip(ped, weapon, 0)
 | 
						|
                AddAmmoToPed(ped, weapon, retval + ammoclip)
 | 
						|
                TriggerServerEvent('weapons:server:AddWeaponAmmo', CurrentWeaponData, total + retval)
 | 
						|
                --TriggerServerEvent("weapons:server:UpdateWeaponAmmo", CurrentWeaponData, total + retval)
 | 
						|
                TriggerServerEvent('weapons:server:removeWeaponAmmoItem', itemData)
 | 
						|
            end
 | 
						|
        end, CurrentWeaponData)
 | 
						|
    else
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_MAX_AMMO'), 'error')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:AddAmmo', function(ammoType, amount, itemData, masterAmmo)
 | 
						|
    local ped = PlayerPedId()
 | 
						|
    if IsPedReloading(ped) then
 | 
						|
        return -- SendTextMessage('Do not spam the reload', 'error')
 | 
						|
    end
 | 
						|
    local weapon = GetSelectedPedWeapon(ped)
 | 
						|
    if not CurrentWeaponData or not WeaponList[weapon] or WeaponList[weapon]['name'] == 'weapon_unarmed' then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_WEAPON'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local weaponAmmoType = type(WeaponList[weapon]['ammotype']) == 'table' and WeaponList[weapon]['ammotype'] or { WeaponList[weapon]['ammotype'] }
 | 
						|
    if not table.includes(weaponAmmoType, ammoType:upper()) then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_AMMO'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local total = GetAmmoInPedWeapon(ped, weapon)
 | 
						|
    local retval = GetMaxAmmoInClip(ped, weapon, 1)
 | 
						|
    local _, ammoclip = GetAmmoInClip(ped, weapon)
 | 
						|
    local _, maxammo = GetMaxAmmo(ped, weapon)
 | 
						|
    if IsPedInAnyVehicle(ped, false) and Config.ForceToOnlyOneMagazine then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_VEHICLE_ITEMS'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    if Config.ForceToOnlyOneMagazine and ammoclip > 0 then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_MAGAZINE_LIMIT'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    if retval then
 | 
						|
        retval = tonumber(retval)
 | 
						|
        itemData = lib.callback.await('weapons:GetWeaponAmmoItem', 0, ammoType, masterAmmo)
 | 
						|
 | 
						|
        if not itemData then
 | 
						|
            print('Nice try forehead :)')
 | 
						|
            return
 | 
						|
        end
 | 
						|
 | 
						|
        if maxammo ~= total then
 | 
						|
            TriggerServerCallback('weapon:server:GetWeaponAmmo', function(ammo)
 | 
						|
                if ammo then
 | 
						|
                    SetAmmoInClip(ped, weapon, 0)
 | 
						|
                    AddAmmoToPed(ped, weapon, retval + ammoclip)
 | 
						|
                    TriggerServerEvent('weapons:server:AddWeaponAmmo', CurrentWeaponData, total + retval)
 | 
						|
                    --TriggerServerEvent("weapons:server:UpdateWeaponAmmo", CurrentWeaponData, total + retval)
 | 
						|
                    TriggerServerEvent('weapons:server:removeWeaponAmmoItem', itemData)
 | 
						|
                end
 | 
						|
            end, CurrentWeaponData)
 | 
						|
        else
 | 
						|
            SendTextMessage(Lang('INVENTORY_NOTIFICATION_MAX_AMMO'), 'error')
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:ConfigureTint')
 | 
						|
AddEventHandler('weapons:client:ConfigureTint', function(ItemData)
 | 
						|
    TintItemData = ItemData
 | 
						|
    SetFocus(true)
 | 
						|
    SendNUIMessage({
 | 
						|
        action = 'showTintMenu'
 | 
						|
    })
 | 
						|
end)
 | 
						|
 | 
						|
function closeGui()
 | 
						|
    SetFocus(false)
 | 
						|
    SendNUIMessage({ action = 'hide' })
 | 
						|
end
 | 
						|
 | 
						|
RegisterNUICallback('quit', function(data, cb)
 | 
						|
    closeGui()
 | 
						|
    TintItemData = {}
 | 
						|
    cb('ok')
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNUICallback('addtinturl', function(data, cb)
 | 
						|
    closeGui()
 | 
						|
    SendTextMessage(Lang('INVENTORY_NOTIFICATION_CUSTOM_TINT_ADDED') .. ' ' .. data.urldatatint, 'success')
 | 
						|
    local tinturl = tostring(data.urldatatint)
 | 
						|
    TriggerServerEvent('weapons:server:AddUrlTint', TintItemData, tinturl)
 | 
						|
    Wait(5)
 | 
						|
    TintItemData = {}
 | 
						|
    cb('ok')
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('weapons:client:EquipAttachment', function(ItemData, attachment, WeaponData)
 | 
						|
    if WeaponData then
 | 
						|
        TriggerServerEvent('weapons:server:EquipAttachment', ItemData, WeaponData, Config.WeaponAttachments[WeaponData.name:upper()][attachment], true)
 | 
						|
        return
 | 
						|
    end
 | 
						|
    local ped = PlayerPedId()
 | 
						|
    local weapon = GetSelectedPedWeapon(ped)
 | 
						|
    local WeaponData = WeaponList[weapon]
 | 
						|
    if weapon == `WEAPON_UNARMED` then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_WEAPON'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    WeaponData.name = WeaponData.name:upper()
 | 
						|
    if not Config.WeaponAttachments[WeaponData.name] then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_ATTACHMENT_NOT_COMPATIBLE'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    if not Config.WeaponAttachments[WeaponData.name][attachment] then
 | 
						|
        SendTextMessage(Lang('INVENTORY_NOTIFICATION_ATTACHMENT_NOT_COMPATIBLE'), 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    if Config.WeaponAttachments[WeaponData.name][attachment]['item'] == ItemData.name then
 | 
						|
        TriggerServerEvent('weapons:server:EquipAttachment', ItemData, CurrentWeaponData, Config.WeaponAttachments[WeaponData.name][attachment])
 | 
						|
        return
 | 
						|
    end
 | 
						|
    SendTextMessage(Lang('INVENTORY_NOTIFICATION_ATTACHMENT_NOT_COMPATIBLE'), 'error')
 | 
						|
end)
 | 
						|
 | 
						|
function SplitStr(str, delimiter)
 | 
						|
    local result = {}
 | 
						|
    local from = 1
 | 
						|
    local delim_from, delim_to = string.find(str, delimiter, from)
 | 
						|
    while delim_from do
 | 
						|
        result[#result + 1] = string.sub(str, from, delim_from - 1)
 | 
						|
        from = delim_to + 1
 | 
						|
        delim_from, delim_to = string.find(str, delimiter, from)
 | 
						|
    end
 | 
						|
    result[#result + 1] = string.sub(str, from)
 | 
						|
    return result
 | 
						|
end
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    SetWeaponsNoAutoswap(true)
 | 
						|
end)
 | 
						|
 | 
						|
LastUpdatedAmmoTime = nil
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        local ped = PlayerPedId()
 | 
						|
        if IsPedArmed(ped, 7) == 1 and (IsControlJustReleased(0, 24) or IsDisabledControlJustReleased(0, 24)) then
 | 
						|
            local weapon = GetSelectedPedWeapon(ped)
 | 
						|
            local ammo = GetAmmoInPedWeapon(ped, weapon)
 | 
						|
            TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, tonumber(ammo))
 | 
						|
            CurrentWeaponData.info.ammo = ammo
 | 
						|
            LastUpdatedAmmoTime = GetGameTimer()
 | 
						|
            if MultiplierAmount > 0 then
 | 
						|
                TriggerServerEvent('weapons:server:UpdateWeaponQuality', CurrentWeaponData, MultiplierAmount, ammo)
 | 
						|
                MultiplierAmount = 0
 | 
						|
            end
 | 
						|
        end
 | 
						|
        Wait(0)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        local ped = PlayerPedId()
 | 
						|
        if CurrentWeaponData and next(CurrentWeaponData) then
 | 
						|
            if IsPedShooting(ped) or IsControlJustPressed(0, 24) then
 | 
						|
                local weapon = GetSelectedPedWeapon(ped)
 | 
						|
                if CanShoot then
 | 
						|
                    if weapon and weapon ~= 0 and WeaponList[weapon] then
 | 
						|
                        TriggerServerCallback('prison:server:checkThrowable', function(result)
 | 
						|
                            if result or GetAmmoInPedWeapon(ped, weapon) <= 0 then return end
 | 
						|
                            MultiplierAmount += 1
 | 
						|
                        end, weapon)
 | 
						|
                        Wait(200)
 | 
						|
                    end
 | 
						|
                else
 | 
						|
                    if weapon ~= `WEAPON_UNARMED` then
 | 
						|
                        TriggerEvent(Config.InventoryPrefix .. ':client:CheckWeapon', WeaponList[weapon]['name'])
 | 
						|
                        SendTextMessage(Lang('INVENTORY_NOTIFICATION_WEAPON_BROKEN'), 'error')
 | 
						|
                        MultiplierAmount = 0
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        Wait(0)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent(Config.InventoryPrefix .. ':client:LegacyFuel', function(fuel)
 | 
						|
    Debug('Your gasoline can has: %', fuel)
 | 
						|
    TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, fuel)
 | 
						|
    TriggerServerEvent('weapons:server:UpdateWeaponQuality', CurrentWeaponData, 1, fuel)
 | 
						|
end)
 | 
						|
 | 
						|
---@param data ServerProgressBar
 | 
						|
lib.callback.register('inventory:progressBarSync', function(data)
 | 
						|
    Debug('Progress bar sync: ', data)
 | 
						|
    local success = ProgressBarSync(data.name, data.label, data.duration, data.useWhileDead, data.canCancel, data.disableControls, data.anim, data.prop)
 | 
						|
    return success
 | 
						|
end)
 | 
						|
 | 
						|
CreateThread(function()
 | 
						|
    while true do
 | 
						|
        local inRange = false
 | 
						|
        local ped = PlayerPedId()
 | 
						|
        local pos = GetEntityCoords(ped)
 | 
						|
        for k, data in pairs(Config.WeaponRepairPoints) do
 | 
						|
            local distance = #(pos - data.coords)
 | 
						|
            if distance < 10 then
 | 
						|
                inRange = true
 | 
						|
                if distance < 1 then
 | 
						|
                    if data.IsRepairing then
 | 
						|
                        if data.RepairingData.CitizenId ~= GetPlayerIdentifier() then
 | 
						|
                            DrawText3Ds(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_NOT_AVAILABLE'))
 | 
						|
                        else
 | 
						|
                            if not data.RepairingData.Ready then
 | 
						|
                                DrawText3Ds(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_REPAIRED'))
 | 
						|
                            else
 | 
						|
                                DrawText3D(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_TAKE'), 'repair_take1', 'E')
 | 
						|
                            end
 | 
						|
                        end
 | 
						|
                    else
 | 
						|
                        if CurrentWeaponData and next(CurrentWeaponData) then
 | 
						|
                            if not data.RepairingData.Ready then
 | 
						|
                                local WeaponData = WeaponList[GetHashKey(CurrentWeaponData.name)]
 | 
						|
                                DrawText3D(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_PRICE') .. Config.WeaponRepairCosts[WeaponData.weapontype], 'repair_weapon', 'E')
 | 
						|
                                if IsControlJustPressed(0, 38) then
 | 
						|
                                    TriggerServerCallback('weapons:server:RepairWeapon', function(HasMoney)
 | 
						|
                                        if HasMoney then
 | 
						|
                                            CurrentWeaponData = {}
 | 
						|
                                        end
 | 
						|
                                    end, k, CurrentWeaponData)
 | 
						|
                                end
 | 
						|
                            else
 | 
						|
                                if data.RepairingData.CitizenId ~= GetPlayerIdentifier() then
 | 
						|
                                    DrawText3Ds(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_NOT_AVAILABLE'))
 | 
						|
                                else
 | 
						|
                                    DrawText3D(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_TAKE'), 'repair_take2', 'E')
 | 
						|
                                    if IsControlJustPressed(0, 38) then
 | 
						|
                                        TriggerServerEvent('weapons:server:TakeBackWeapon', k, data)
 | 
						|
                                    end
 | 
						|
                                end
 | 
						|
                            end
 | 
						|
                        else
 | 
						|
                            if data.RepairingData.CitizenId == nil then
 | 
						|
                                DrawText3Ds(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_NO_WEAPON'))
 | 
						|
                            elseif data.RepairingData.CitizenId == GetPlayerIdentifier() then
 | 
						|
                                DrawText3D(data.coords.x, data.coords.y, data.coords.z, Lang('INVENTORY_TEXT_REPAIR_TAKE'), 'repair_take3', 'E')
 | 
						|
                                if IsControlJustPressed(0, 38) then
 | 
						|
                                    TriggerServerEvent('weapons:server:TakeBackWeapon', k, data)
 | 
						|
                                end
 | 
						|
                            end
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        if not inRange then
 | 
						|
            Wait(1250)
 | 
						|
        end
 | 
						|
        Wait(3)
 | 
						|
    end
 | 
						|
end)
 |