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)