1
0
Fork 0
forked from Simnation/Main
Main/resources/[inventory]/qs-inventory/client/modules/weapons.lua
2025-06-07 08:51:21 +02:00

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)