forked from Simnation/Main
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)
|