fix(qb-core): add global CreateUsableItem alias for qs-inventory compatibility
qs-inventory apelează CreateUsableItem ca funcție globală, dar qb-core definea doar QBCore.Functions.CreateUseableItem (cu 'e'). Adăugat alias global + fix 16 stringuri sparte în items.lua care blocau parsarea.
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,310 @@
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
function GetPlayerData()
|
||||
return ESX.GetPlayerData()
|
||||
end
|
||||
|
||||
function TriggerServerCallback(name, cb, ...)
|
||||
ESX.TriggerServerCallback(name, cb, ...)
|
||||
end
|
||||
|
||||
local playerLoaded = ESX.IsPlayerLoaded()
|
||||
function IsPlayerLoaded()
|
||||
return playerLoaded
|
||||
end
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
|
||||
PlayerData = xPlayer
|
||||
LocalPlayer.state:set('inv_busy', false, true)
|
||||
Wait(1250)
|
||||
for k, data in pairs(Config.WeaponRepairPoints) do
|
||||
Config.WeaponRepairPoints[k].IsRepairing = data.IsRepairing
|
||||
Config.WeaponRepairPoints[k].RepairingData = data.RepairingData
|
||||
end
|
||||
if Config.Crafting then
|
||||
CreateBlips()
|
||||
end
|
||||
Wait(5000)
|
||||
playerLoaded = true
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:onPlayerLogout')
|
||||
AddEventHandler('esx:onPlayerLogout', function()
|
||||
PlayerData = {}
|
||||
LocalPlayer.state:set('inv_busy', true, true)
|
||||
RemoveAllNearbyDrops()
|
||||
for k in pairs(Config.WeaponRepairPoints) do
|
||||
Config.WeaponRepairPoints[k].IsRepairing = false
|
||||
Config.WeaponRepairPoints[k].RepairingData = {}
|
||||
end
|
||||
TriggerServerEvent('inventory:handleLogout')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:setJob', function()
|
||||
PlayerData = GetPlayerData()
|
||||
if Config.Crafting then
|
||||
CreateBlips()
|
||||
end
|
||||
end)
|
||||
|
||||
AddEventHandler('esx_status:onTick', function(status)
|
||||
TriggerEvent('esx_status:getStatus', 'hunger', function(status)
|
||||
hunger = status.val / 10000
|
||||
end)
|
||||
TriggerEvent('esx_status:getStatus', 'thirst', function(status)
|
||||
thirst = status.val / 10000
|
||||
end)
|
||||
end)
|
||||
|
||||
function GetPlayerIdentifier()
|
||||
return GetPlayerData().identifier
|
||||
end
|
||||
|
||||
function GetPlayersInArea()
|
||||
local playerPed = PlayerPedId()
|
||||
return ESX.Game.GetPlayersInArea(GetEntityCoords(playerPed), 3.0)
|
||||
end
|
||||
|
||||
function GetJobName()
|
||||
return GetPlayerData()?.job?.name
|
||||
end
|
||||
|
||||
function GetJobGrade()
|
||||
return GetPlayerData().job.grade
|
||||
end
|
||||
|
||||
function GetGang()
|
||||
return false
|
||||
end
|
||||
|
||||
function GetGangLevel()
|
||||
return false
|
||||
end
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
if type == 'inform' then
|
||||
exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fa-solid fa-file')
|
||||
elseif type == 'error' then
|
||||
exports['qs-interface']:AddNotify(msg, 'Error', 2500, 'fas fa-bug')
|
||||
elseif type == 'success' then
|
||||
exports['qs-interface']:AddNotify(msg, 'Success', 2500, 'fas fa-thumbs-up')
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
elseif type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
elseif type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function ShowHelpNotification(msg)
|
||||
AddTextEntry('helpNotification', msg)
|
||||
BeginTextCommandDisplayHelp('helpNotification')
|
||||
EndTextCommandDisplayHelp(0, true, true, -1)
|
||||
end
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key)
|
||||
local _id = id
|
||||
if not texts[_id] then
|
||||
CreateThread(function()
|
||||
texts[_id] = 5
|
||||
while texts[_id] > 0 do
|
||||
texts[_id] = texts[_id] - 1
|
||||
Wait(0)
|
||||
end
|
||||
texts[_id] = nil
|
||||
exports['qs-textui']:DeleteDrawText3D(id)
|
||||
Debug('Deleted text', id)
|
||||
end)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
|
||||
end
|
||||
texts[_id] = 5
|
||||
end
|
||||
else
|
||||
function DrawText3D(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = text:len() / 370
|
||||
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
end
|
||||
|
||||
function DrawText3Ds(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = string.len(text) / 370
|
||||
DrawRect(0.0, 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
|
||||
function ToggleHud(bool)
|
||||
if bool then
|
||||
Debug('Event to show the hud [client/custom/framework/esx.lua line 174]')
|
||||
DisplayRadar(true) -- You can enable or disable mini-map here
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
exports['qs-interface']:ToggleHud(true)
|
||||
end
|
||||
else
|
||||
Debug('Event to hide the hud [client/custom/framework/esx.lua line 174]')
|
||||
DisplayRadar(false) -- You can enable or disable mini-map here
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
exports['qs-interface']:ToggleHud(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
local success = exports['qs-interface']:ProgressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
})
|
||||
if success then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
return
|
||||
end
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
|
||||
function ProgressBarSync(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
return exports['qs-interface']:ProgressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = animation,
|
||||
prop = prop
|
||||
})
|
||||
end
|
||||
return lib.progressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = animation,
|
||||
prop = prop
|
||||
})
|
||||
end
|
||||
|
||||
function SetPlayerStatus(values)
|
||||
for name, value in pairs(values) do
|
||||
if value > 0 then
|
||||
TriggerEvent('esx_status:add', name, value)
|
||||
else
|
||||
TriggerEvent('esx_status:remove', name, -value)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function DropMarker(coords)
|
||||
DrawMarker(20, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.3, 0.15, 120, 10, 20, 155, false, false, false, 1, false, false, false)
|
||||
end
|
||||
|
||||
function CanUseInventory()
|
||||
local ped = PlayerPedId()
|
||||
local wasabiHas = GetResourceState('wasabi_ambulance') == 'started'
|
||||
if wasabiHas and exports.wasabi_ambulance:isPlayerDead() then
|
||||
return false
|
||||
end
|
||||
if LocalPlayer.state.isDead and LocalPlayer.state.isDead == 1 then
|
||||
return false
|
||||
end
|
||||
if GetEntityHealth(ped) >= 1 then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function checkEntityDead(id, entity)
|
||||
if Player(id).state.isDead then
|
||||
return true
|
||||
end
|
||||
local check = false
|
||||
if GetEntityHealth(entity) <= 1 then
|
||||
check = true
|
||||
end
|
||||
return check
|
||||
end
|
||||
|
||||
function reputationCrafing(rep)
|
||||
--- @param rep Name of reputation
|
||||
return 99999
|
||||
end
|
||||
|
||||
RegisterNetEvent('qs-inventory:client:updateItem', function(item, data)
|
||||
if not ItemList[item] then
|
||||
return
|
||||
end
|
||||
ItemList[item] = data
|
||||
end)
|
||||
@@ -0,0 +1,315 @@
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
if not Config.QBX then
|
||||
WeaponList = QBCore.Shared.Weapons
|
||||
ItemList = QBCore.Shared.Items
|
||||
end
|
||||
|
||||
local playerLoaded = LocalPlayer.state['isLoggedIn']
|
||||
function IsPlayerLoaded()
|
||||
return playerLoaded
|
||||
end
|
||||
|
||||
function GetPlayerData()
|
||||
return QBCore.Functions.GetPlayerData()
|
||||
end
|
||||
|
||||
function TriggerServerCallback(name, cb, ...)
|
||||
QBCore.Functions.TriggerCallback(name, cb, ...)
|
||||
end
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = GetPlayerData()
|
||||
LocalPlayer.state:set('inv_busy', false, true)
|
||||
Wait(1250)
|
||||
for k, data in pairs(Config.WeaponRepairPoints) do
|
||||
Config.WeaponRepairPoints[k].IsRepairing = data.IsRepairing
|
||||
Config.WeaponRepairPoints[k].RepairingData = data.RepairingData
|
||||
end
|
||||
if Config.Crafting then
|
||||
CreateBlips()
|
||||
end
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OnLoadUpdateCash')
|
||||
Wait(5000)
|
||||
playerLoaded = true
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerUnload', function()
|
||||
PlayerData = {}
|
||||
LocalPlayer.state:set('inv_busy', true, true)
|
||||
RemoveAllNearbyDrops()
|
||||
for k in pairs(Config.WeaponRepairPoints) do
|
||||
Config.WeaponRepairPoints[k].IsRepairing = false
|
||||
Config.WeaponRepairPoints[k].RepairingData = {}
|
||||
end
|
||||
TriggerServerEvent('inventory:handleLogout')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Player:SetPlayerData', function(val)
|
||||
PlayerData = val
|
||||
if Config.Crafting then
|
||||
CreateBlips()
|
||||
end
|
||||
end)
|
||||
|
||||
function GetPlayerIdentifier()
|
||||
return GetPlayerData().citizenid
|
||||
end
|
||||
|
||||
function GetPlayersInArea()
|
||||
local playerPed = PlayerPedId()
|
||||
return QBCore.Functions.GetPlayersFromCoords(GetEntityCoords(playerPed), 3.0)
|
||||
end
|
||||
|
||||
function GetJobName()
|
||||
return GetPlayerData()?.job?.name
|
||||
end
|
||||
|
||||
function GetJobGrade()
|
||||
return GetPlayerData().job.grade
|
||||
end
|
||||
|
||||
function GetGang()
|
||||
return false
|
||||
end
|
||||
|
||||
function GetGangLevel()
|
||||
return false
|
||||
end
|
||||
|
||||
function SendTextMessage(msg, type)
|
||||
if type == 'inform' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'inform'
|
||||
})
|
||||
end
|
||||
if type == 'error' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'error'
|
||||
})
|
||||
end
|
||||
if type == 'success' then
|
||||
lib.notify({
|
||||
title = 'Inventory',
|
||||
description = msg,
|
||||
type = 'success'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function ShowHelpNotification(msg)
|
||||
AddTextEntry('helpNotification', msg)
|
||||
BeginTextCommandDisplayHelp('helpNotification')
|
||||
EndTextCommandDisplayHelp(0, true, true, -1)
|
||||
end
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key)
|
||||
local _id = id
|
||||
if not texts[_id] then
|
||||
CreateThread(function()
|
||||
texts[_id] = 5
|
||||
while texts[_id] > 0 do
|
||||
texts[_id] = texts[_id] - 1
|
||||
Wait(0)
|
||||
end
|
||||
texts[_id] = nil
|
||||
exports['qs-textui']:DeleteDrawText3D(id)
|
||||
Debug('Deleted text', id)
|
||||
end)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key)
|
||||
end
|
||||
texts[_id] = 5
|
||||
end
|
||||
else
|
||||
function DrawText3D(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = text:len() / 370
|
||||
DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
end
|
||||
|
||||
function DrawText3Ds(x, y, z, text)
|
||||
SetTextScale(0.35, 0.35)
|
||||
SetTextFont(4)
|
||||
SetTextProportional(1)
|
||||
SetTextColour(255, 255, 255, 215)
|
||||
SetTextEntry('STRING')
|
||||
SetTextCentre(true)
|
||||
AddTextComponentString(text)
|
||||
SetDrawOrigin(x, y, z, 0)
|
||||
DrawText(0.0, 0.0)
|
||||
local factor = string.len(text) / 370
|
||||
DrawRect(0.0, 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75)
|
||||
ClearDrawOrigin()
|
||||
end
|
||||
|
||||
function ToggleHud(bool)
|
||||
if bool then
|
||||
Debug('Event to show the hud [client/custom/framework/esx.lua line 174]')
|
||||
DisplayRadar(true) -- You can enable or disable mini-map here
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
exports['qs-interface']:ToggleHud(true)
|
||||
end
|
||||
else
|
||||
Debug('Event to hide the hud [client/custom/framework/esx.lua line 174]')
|
||||
DisplayRadar(false) -- You can enable or disable mini-map here
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
exports['qs-interface']:ToggleHud(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ProgressBar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
local success = exports['qs-interface']:ProgressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flags
|
||||
},
|
||||
prop = prop
|
||||
})
|
||||
if success then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
return
|
||||
end
|
||||
if lib.progressCircle({
|
||||
duration = duration,
|
||||
label = label,
|
||||
position = 'bottom',
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = {
|
||||
dict = animation.animDict,
|
||||
clip = animation.anim,
|
||||
flag = animation?.flag
|
||||
},
|
||||
prop = prop
|
||||
}) then
|
||||
onFinish()
|
||||
else
|
||||
onCancel()
|
||||
end
|
||||
end
|
||||
|
||||
function ProgressBarSync(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
return exports['qs-interface']:ProgressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = animation,
|
||||
prop = prop
|
||||
})
|
||||
end
|
||||
return lib.progressBar({
|
||||
duration = duration,
|
||||
label = label,
|
||||
useWhileDead = useWhileDead,
|
||||
canCancel = canCancel,
|
||||
disable = disableControls,
|
||||
anim = animation,
|
||||
prop = prop
|
||||
})
|
||||
end
|
||||
|
||||
function DropMarker(coords)
|
||||
DrawMarker(20, coords.x, coords.y, coords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.3, 0.15, 120, 10, 20, 155, false, false, false, 1, false, false, false)
|
||||
end
|
||||
|
||||
function SetPlayerStatus(values)
|
||||
for name, value in pairs(values) do
|
||||
-- compatibility for ESX style values
|
||||
if value > 100 or value < -100 then
|
||||
value = value * 0.0001
|
||||
end
|
||||
|
||||
if name == 'hunger' then
|
||||
TriggerServerEvent('inventory:consumables:addHunger', QBCore.Functions.GetPlayerData().metadata.hunger + value)
|
||||
elseif name == 'thirst' then
|
||||
TriggerServerEvent('inventory:consumables:addThirst', QBCore.Functions.GetPlayerData().metadata.thirst + value)
|
||||
elseif name == 'stress' then
|
||||
if value > 0 then
|
||||
TriggerServerEvent('hud:server:GainStress', value)
|
||||
else
|
||||
value = math.abs(value)
|
||||
TriggerServerEvent('hud:server:RelieveStress', value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CanUseInventory()
|
||||
local check = false
|
||||
local data = GetPlayerData()
|
||||
if not data.metadata['isdead'] and not data.metadata['inlaststand'] and not data.metadata['ishandcuffed'] and not IsPauseMenuActive() then
|
||||
check = true
|
||||
end
|
||||
return check
|
||||
end
|
||||
|
||||
function checkEntityDead(id, entity)
|
||||
local isDead = false
|
||||
TriggerServerCallback(Config.InventoryPrefix .. ':server:checkDead', function(result)
|
||||
isDead = result
|
||||
end, id)
|
||||
repeat Wait(250) until isDead ~= nil
|
||||
return isDead
|
||||
end
|
||||
|
||||
function reputationCrafing(rep)
|
||||
local PlayerData = QBCore.Functions.GetPlayerData()
|
||||
if not PlayerData then return 0 end
|
||||
|
||||
local reputation = PlayerData.metadata[rep] or 0
|
||||
|
||||
if reputation == nil then
|
||||
reputation = 0
|
||||
end
|
||||
|
||||
return reputation
|
||||
end
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnSharedUpdate', function(type, item, data)
|
||||
if type == 'Items' then
|
||||
ItemList[item] = data
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnSharedUpdateMultiple', function(type, data)
|
||||
if type == 'Items' then
|
||||
for k, v in pairs(data) do
|
||||
ItemList[k] = v
|
||||
end
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,69 @@
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:CraftItems', function(itemName, itemCosts, points, amount, toSlot, rep, time, chance)
|
||||
local ped = PlayerPedId()
|
||||
local itemData = ItemList[itemName:lower()]
|
||||
local randomNum = math.random(1, 100)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'close',
|
||||
})
|
||||
inInventory = false
|
||||
if itemData['type'] == 'weapon' and tonumber(amount) > 1 then
|
||||
return SendTextMessage(Lang('INVENTORY_NOTIFICATION_CRAFTING_WEAPONS'), 'error')
|
||||
end
|
||||
|
||||
if chance then
|
||||
Debug('Crafting started with a chance of ' .. randomNum .. '% and you had ' .. chance .. '%')
|
||||
else
|
||||
chance = 100
|
||||
Debug('There is no chance option in your configuration or in this item, and the crafting chance is set to 100%')
|
||||
end
|
||||
|
||||
isCrafting = true
|
||||
time = time or 1000
|
||||
ProgressBar('crafting_item', Lang('INVENTORY_PROGRESS_CRAFTING'), (time * amount), false, false, {
|
||||
move = true,
|
||||
car = true,
|
||||
mouse = false,
|
||||
combat = true,
|
||||
}, {
|
||||
animDict = 'mini@repair',
|
||||
anim = 'fixing_a_player',
|
||||
flags = 1,
|
||||
}, {}, {}, function()
|
||||
if randomNum <= chance then
|
||||
Debug('Crafting successful with ' .. randomNum .. '% chance and you had ' .. chance .. '%')
|
||||
itemData.count = tonumber(amount)
|
||||
StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0)
|
||||
else
|
||||
Debug('Crafting failed with ' .. randomNum .. '% chance and you had ' .. chance .. '%')
|
||||
StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0)
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_CRAFTING_FAILED'), 'inform')
|
||||
Wait(550)
|
||||
TaskPlayAnim(ped, 'gestures@m@standing@casual', 'gesture_damn', 8.0, -8.0, -1, 1, 0, false, false, false)
|
||||
Wait(1250)
|
||||
StopAnimTask(ped, 'gestures@m@standing@casual', 'gesture_damn', 1.0)
|
||||
end
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:CraftItems', itemName, itemCosts, points, amount, toSlot, rep, randomNum, chance)
|
||||
isCrafting = false
|
||||
end, function()
|
||||
StopAnimTask(ped, 'mini@repair', 'fixing_a_player', 1.0)
|
||||
isCrafting = false
|
||||
end)
|
||||
TriggerScreenblurFadeOut(300)
|
||||
if Config.Clothing then DeletePedScreen() end
|
||||
end)
|
||||
|
||||
-- RegisterCommand('tt', function(source, args)
|
||||
-- ProgressBar('crafting_item', Lang('INVENTORY_PROGRESS_CRAFTING'), (1000), false, false, {
|
||||
-- move = true,
|
||||
-- car = true,
|
||||
-- mouse = false,
|
||||
-- combat = true,
|
||||
-- }, {
|
||||
-- animDict = 'mini@repair',
|
||||
-- anim = 'fixing_a_player',
|
||||
-- flags = 1,
|
||||
-- }, {}, {}, function()
|
||||
-- end, function()
|
||||
-- end)
|
||||
-- end, false)
|
||||
@@ -0,0 +1,10 @@
|
||||
--[[
|
||||
We recommend not modifying anything on this side, the Starter Items
|
||||
are all in your server/custom/framework/esx.lua, it won't work in
|
||||
qb-core since that framework has its native ones that do it automatically.
|
||||
]]
|
||||
|
||||
AddEventHandler(Config.InventoryPrefix .. ':client:GiveStarterItems', function()
|
||||
local id = PlayerId()
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:GiveStarterItems', id)
|
||||
end)
|
||||
@@ -0,0 +1,137 @@
|
||||
local function SyncEquippedWeaponAmmoOnOpen(inventory)
|
||||
if not inventory then return inventory end
|
||||
|
||||
local ped = cache.ped
|
||||
local weaponHash = GetSelectedPedWeapon(ped)
|
||||
local weaponData = WeaponList and WeaponList[weaponHash]
|
||||
if not weaponData or weaponData.name == 'weapon_unarmed' then
|
||||
return inventory
|
||||
end
|
||||
|
||||
local ammo = GetAmmoInPedWeapon(ped, weaponHash) or 0
|
||||
|
||||
-- Prefer the equipped slot if CurrentWeaponData is available.
|
||||
local preferredSlot = CurrentWeaponData and CurrentWeaponData.slot
|
||||
if preferredSlot and inventory[preferredSlot] and inventory[preferredSlot].name == weaponData.name then
|
||||
inventory[preferredSlot].info = inventory[preferredSlot].info or {}
|
||||
inventory[preferredSlot].info.ammo = ammo
|
||||
return inventory
|
||||
end
|
||||
|
||||
for _, item in pairs(inventory) do
|
||||
if item and item.type == 'weapon' and item.name == weaponData.name then
|
||||
item.info = item.info or {}
|
||||
item.info.ammo = ammo
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return inventory
|
||||
end
|
||||
|
||||
local checkDistanceInventories = {
|
||||
'shop',
|
||||
'stash',
|
||||
'crafting',
|
||||
'attachment_crafting',
|
||||
'traphouse',
|
||||
'customcrafting'
|
||||
}
|
||||
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:OpenInventory', function(PlayerAmmo, inventory, other, otherName)
|
||||
if not inventory then return Error('Inventory is not working, clear the inventory column [sql] to continue.') end
|
||||
inventory = FormatItemsToInfo(inventory)
|
||||
ToggleHud(false)
|
||||
ToggleHotbar(false)
|
||||
SetFocus(true)
|
||||
IdleCamera(true)
|
||||
SetPedCanPlayAmbientAnims(PlayerPedId(), false)
|
||||
SetResourceKvp('idleCam', 'off')
|
||||
|
||||
if other then
|
||||
currentOtherInventory = other.name
|
||||
end
|
||||
|
||||
OpenedInventoryCoords = GetEntityCoords(PlayerPedId())
|
||||
|
||||
TriggerServerCallback(Config.InventoryPrefix .. ':server:QualityDecay', function(data)
|
||||
local hungerValue = hunger
|
||||
local thirstValue = thirst
|
||||
if Config.Framework == 'qb' then
|
||||
local data = GetPlayerData()
|
||||
hungerValue = data.metadata and data.metadata.hunger
|
||||
thirstValue = data.metadata and data.metadata.thirst
|
||||
end
|
||||
|
||||
local PlayerSlots = Config.InventoryWeight.slots
|
||||
if not Config.BlockedSlot then
|
||||
PlayerSlots = Config.InventoryWeight.slots - 1
|
||||
end
|
||||
|
||||
inventory = data.inventory
|
||||
inventory = SyncEquippedWeaponAmmoOnOpen(inventory)
|
||||
other = data.other
|
||||
|
||||
data = GetPlayerData()
|
||||
if Config.Framework == 'esx' then
|
||||
firstName = data.firstName or ''
|
||||
lastName = data.lastName or ''
|
||||
for i = 1, #data.accounts do
|
||||
if data.accounts[i].name == 'money' then
|
||||
money = data.accounts[i].money or 'Not found'
|
||||
elseif data.accounts[i].name == 'bank' then
|
||||
bank = data.accounts[i].money or 'Not found'
|
||||
elseif data.accounts[i].name == 'black_money' then
|
||||
blackmoney = data.accounts[i].money or 'Not found'
|
||||
end
|
||||
end
|
||||
elseif Config.Framework == 'qb' then
|
||||
firstName = data.charinfo.firstname or ''
|
||||
lastName = data.charinfo.lastname or ''
|
||||
money = data.money.cash or 'Not found'
|
||||
bank = data.money.bank or 'Not found'
|
||||
blackmoney = data.money.crypto or 'Not found'
|
||||
end
|
||||
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'open',
|
||||
inventory = inventory,
|
||||
slots = PlayerSlots,
|
||||
other = other,
|
||||
maxweight = Config.InventoryWeight.weight,
|
||||
Ammo = PlayerAmmo,
|
||||
playerName = firstName .. ' ' .. lastName,
|
||||
logo = Config.Logo,
|
||||
openAnimation = Config.OpenInventoryScene,
|
||||
optionClothes = Config.InventoryOptions.clothes,
|
||||
optionConfiguration = Config.InventoryOptions.configuration,
|
||||
optionHealth = Config.InventoryOptions.health,
|
||||
optionArmor = Config.InventoryOptions.armor,
|
||||
optionHunger = Config.InventoryOptions.hunger,
|
||||
optionThirst = Config.InventoryOptions.thirst,
|
||||
optionId = Config.InventoryOptions.id,
|
||||
optionMoney = Config.InventoryOptions.money,
|
||||
optionBank = Config.InventoryOptions.bank,
|
||||
optionBlackMoney = Config.InventoryOptions.blackmoney,
|
||||
playerhp = GetEntityHealth(PlayerPedId()),
|
||||
playerarmor = GetPedArmour(PlayerPedId()),
|
||||
playerhunger = hungerValue or 0,
|
||||
playerthirst = thirstValue or 0,
|
||||
playerId = GetPlayerServerId(PlayerId()),
|
||||
playerMoney = money,
|
||||
playerBank = bank,
|
||||
playerBlackMoney = blackmoney,
|
||||
notStolenItems = Config.notStolenItems,
|
||||
notStoredItems = Config.notStoredItems,
|
||||
labelChanger = Config.LabelChange
|
||||
})
|
||||
inInventory = true
|
||||
if table.includes(checkDistanceInventories, otherName) then
|
||||
CheckNearbyOtherInventory()
|
||||
end
|
||||
end, inventory, other)
|
||||
|
||||
if not Config.Handsup then return end
|
||||
checkPlayerRobbery(other)
|
||||
end)
|
||||
@@ -0,0 +1,48 @@
|
||||
if not Config.UseTarget then
|
||||
local nearby = false
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local sleep = 1000
|
||||
if nearby then
|
||||
DrawText3D(Config.SellItems[nearby].coords.x, Config.SellItems[nearby].coords.y, Config.SellItems[nearby].coords.z, Lang('INVENTORY_TEXT_SELLING'), 'selling', 'E')
|
||||
sleep = 1
|
||||
if IsControlJustPressed(0, 38) then
|
||||
local PawnshopItems = {}
|
||||
PawnshopItems.label = nearby
|
||||
PawnshopItems.items = Config.SellItems[nearby].items
|
||||
PawnshopItems.slots = #Config.SellItems[nearby].items
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'selling', 'itemselling_' .. nearby, PawnshopItems)
|
||||
end
|
||||
end
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
for k, v in pairs(Config.SellItems) do
|
||||
if v.blip and v.blip.active then
|
||||
local ff = v.blip
|
||||
local blip = AddBlipForCoord(v.coords)
|
||||
SetBlipSprite(blip, ff.sprite)
|
||||
SetBlipColour(blip, ff.color)
|
||||
SetBlipScale(blip, ff.scale)
|
||||
BeginTextCommandSetBlipName('STRING')
|
||||
AddTextComponentString(ff.name)
|
||||
EndTextCommandSetBlipName(blip)
|
||||
SetBlipAsShortRange(blip, true)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local playercoords = GetEntityCoords(PlayerPedId())
|
||||
local finded = false
|
||||
for k, v in pairs(Config.SellItems) do
|
||||
if #(playercoords - v.coords) <= 2 then finded = k end
|
||||
end
|
||||
nearby = finded
|
||||
Wait(700)
|
||||
end
|
||||
end)
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:UseWeapon', function(weaponData, shootbool)
|
||||
if FiringWeapon then
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_STOP_FIRING'), 'error')
|
||||
return false
|
||||
end
|
||||
local ped = PlayerPedId()
|
||||
local weaponName = tostring(weaponData.name)
|
||||
local weaponHash = joaat(weaponData.name)
|
||||
for i = 1, #Config.WeaponTints do
|
||||
if tostring(GetHashKey(weaponName)) == Config.WeaponTints[i].hash then
|
||||
AddReplaceTexture(Config.WeaponTints[i].ytd, Config.WeaponTints[i].texture, Config.WeaponTints[i].ytd, Config.WeaponTints[i].texture)
|
||||
break
|
||||
end
|
||||
end
|
||||
if currentWeapon == weaponName then
|
||||
TriggerEvent('weapons:client:DrawWeapon', nil)
|
||||
SetCurrentPedWeapon(ped, `WEAPON_UNARMED`, true)
|
||||
RemoveAllPedWeapons(ped, true)
|
||||
TriggerEvent('weapons:client:SetCurrentWeapon', nil, shootbool)
|
||||
currentWeapon = nil
|
||||
elseif weaponName == 'weapon_stickybomb' or weaponName == 'weapon_pipebomb' or weaponName == 'weapon_smokegrenade' or weaponName == 'weapon_flare' or weaponName == 'weapon_proxmine' or weaponName == 'weapon_ball' or weaponName == 'weapon_molotov' or weaponName == 'weapon_grenade' or weaponName == 'weapon_bzgas' then
|
||||
TriggerEvent('weapons:client:DrawWeapon', weaponName)
|
||||
GiveWeaponToPed(ped, weaponHash, 1, false, false)
|
||||
SetPedAmmo(ped, weaponHash, 1)
|
||||
SetCurrentPedWeapon(ped, weaponHash, true)
|
||||
TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool)
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:RemoveItem', weaponName, 1)
|
||||
currentWeapon = weaponName
|
||||
elseif weaponName == 'weapon_snowball' then
|
||||
TriggerEvent('weapons:client:DrawWeapon', weaponName)
|
||||
GiveWeaponToPed(ped, weaponHash, 10, false, false)
|
||||
SetPedAmmo(ped, weaponHash, 10)
|
||||
SetCurrentPedWeapon(ped, weaponHash, true)
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:snowball', 'remove')
|
||||
TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool)
|
||||
currentWeapon = weaponName
|
||||
elseif weaponName == 'weapon_petrolcan' then
|
||||
GiveWeaponToPed(ped, weaponHash, 10, false, false)
|
||||
SetPedAmmo(ped, weaponHash, weaponData.info.ammo or 4500)
|
||||
SetCurrentPedWeapon(ped, weaponHash, true)
|
||||
TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool)
|
||||
currentWeapon = weaponName
|
||||
else
|
||||
TriggerEvent('weapons:client:DrawWeapon', weaponName)
|
||||
TriggerEvent('weapons:client:SetCurrentWeapon', weaponData, shootbool)
|
||||
local ammo = tonumber(weaponData.info.ammo) or 0
|
||||
|
||||
if weaponName == 'weapon_petrolcan' or weaponName == 'weapon_fireextinguisher' then
|
||||
ammo = 4000
|
||||
end
|
||||
|
||||
GiveWeaponToPed(ped, weaponHash, ammo, false, false)
|
||||
SetPedAmmo(ped, weaponHash, ammo)
|
||||
SetCurrentPedWeapon(ped, weaponHash, true)
|
||||
|
||||
if weaponData.info.attachments then
|
||||
for _, attachment in pairs(weaponData.info.attachments) do
|
||||
if attachment.tint then
|
||||
if attachment.urltint ~= 'none' then
|
||||
ChangeWeaponTintWithUrl(weaponHash, attachment.urltint)
|
||||
else
|
||||
SetPedWeaponTintIndex(ped, weaponHash, attachment.tint)
|
||||
end
|
||||
else
|
||||
GiveWeaponComponentToPed(ped, weaponHash, joaat(attachment.component))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
currentWeapon = weaponName
|
||||
end
|
||||
end)
|
||||
@@ -0,0 +1,175 @@
|
||||
local isAdminGiveItemOpen = false
|
||||
local currentPlayers = {}
|
||||
local currentItems = {}
|
||||
local selectedPlayer = nil
|
||||
local selectedItem = nil
|
||||
|
||||
-- Open the admin giveitem interface
|
||||
RegisterNetEvent('inventory:admin:openGiveItemInterface', function()
|
||||
Debug('Opening admin interface...')
|
||||
if isAdminGiveItemOpen then
|
||||
return
|
||||
end
|
||||
|
||||
isAdminGiveItemOpen = true
|
||||
SetNuiFocus(true, true)
|
||||
|
||||
-- Get initial data
|
||||
GetOnlinePlayers()
|
||||
GetAllItems()
|
||||
|
||||
-- Open the UI
|
||||
SendNUIMessage({
|
||||
action = 'openAdminGiveItem',
|
||||
data = {
|
||||
title = 'Admin Give Item System',
|
||||
subtitle = 'Player item giving system'
|
||||
}
|
||||
})
|
||||
end)
|
||||
|
||||
-- Get online players
|
||||
function GetOnlinePlayers()
|
||||
lib.callback('inventory:admin:getOnlinePlayers', false, function(players)
|
||||
currentPlayers = players
|
||||
SendNUIMessage({
|
||||
action = 'updatePlayers',
|
||||
data = players
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
-- Get all items
|
||||
function GetAllItems()
|
||||
local items = {}
|
||||
for itemName, itemData in pairs(ItemList) do
|
||||
table.insert(items, {
|
||||
name = itemName,
|
||||
label = itemData.label,
|
||||
type = itemData.type,
|
||||
weight = itemData.weight,
|
||||
unique = itemData.unique or false,
|
||||
image = itemData.image or 'default.png'
|
||||
})
|
||||
end
|
||||
|
||||
-- Sort items alphabetically
|
||||
table.sort(items, function(a, b)
|
||||
return a.label < b.label
|
||||
end)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'updateItems',
|
||||
data = items
|
||||
})
|
||||
end
|
||||
|
||||
-- Search players
|
||||
function SearchPlayers(searchTerm)
|
||||
lib.callback('inventory:admin:searchPlayers', false, function(players)
|
||||
currentPlayers = players
|
||||
SendNUIMessage({
|
||||
action = 'updatePlayers',
|
||||
data = players
|
||||
})
|
||||
end, searchTerm)
|
||||
end
|
||||
|
||||
-- Search items
|
||||
function SearchItems(searchTerm)
|
||||
local items = {}
|
||||
local searchLower = string.lower(searchTerm or '')
|
||||
|
||||
for itemName, itemData in pairs(ItemList) do
|
||||
local itemLabelLower = string.lower(itemData.label)
|
||||
local itemNameLower = string.lower(itemName)
|
||||
|
||||
if searchLower == '' or
|
||||
string.find(itemLabelLower, searchLower, 1, true) or
|
||||
string.find(itemNameLower, searchLower, 1, true) then
|
||||
table.insert(items, {
|
||||
name = itemName,
|
||||
label = itemData.label,
|
||||
type = itemData.type,
|
||||
weight = itemData.weight,
|
||||
unique = itemData.unique or false,
|
||||
image = itemData.image or 'default.png'
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Sort items alphabetically
|
||||
table.sort(items, function(a, b)
|
||||
return a.label < b.label
|
||||
end)
|
||||
|
||||
SendNUIMessage({
|
||||
action = 'updateItems',
|
||||
data = items
|
||||
})
|
||||
end
|
||||
|
||||
function GiveItemToPlayer(targetId, itemName, amount, metadata)
|
||||
lib.callback('inventory:admin:giveItem', false, function(success, message)
|
||||
if success then
|
||||
SendTextMessage(message, 'success')
|
||||
CloseAdminGiveItemInterface()
|
||||
else
|
||||
SendTextMessage(message, 'error')
|
||||
end
|
||||
end, targetId, itemName, amount, metadata)
|
||||
end
|
||||
|
||||
-- Close admin giveitem interface
|
||||
function CloseAdminGiveItemInterface()
|
||||
Debug('Closing admin interface...')
|
||||
isAdminGiveItemOpen = false
|
||||
SetNuiFocus(false, false)
|
||||
SendNUIMessage({
|
||||
action = 'closeAdminGiveItem'
|
||||
})
|
||||
end
|
||||
|
||||
-- NUI Callbacks
|
||||
RegisterNUICallback('closeAdminGiveItem', function(data, cb)
|
||||
CloseAdminGiveItemInterface()
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNUICallback('searchPlayers', function(data, cb)
|
||||
SearchPlayers(data.searchTerm)
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNUICallback('searchItems', function(data, cb)
|
||||
SearchItems(data.searchTerm)
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNUICallback('selectPlayer', function(data, cb)
|
||||
selectedPlayer = data.player
|
||||
SendNUIMessage({
|
||||
action = 'updateSelectedPlayer',
|
||||
data = data.player
|
||||
})
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNUICallback('selectItem', function(data, cb)
|
||||
selectedItem = data.item
|
||||
SendNUIMessage({
|
||||
action = 'updateSelectedItem',
|
||||
data = data.item
|
||||
})
|
||||
cb('ok')
|
||||
end)
|
||||
|
||||
RegisterNUICallback('giveItem', function(data, cb)
|
||||
local player = data.player
|
||||
local item = data.item
|
||||
local amount = tonumber(data.amount) or 1
|
||||
local metadata = data.metadata or ''
|
||||
|
||||
GiveItemToPlayer(player.id, item.name, amount, metadata)
|
||||
cb('ok')
|
||||
end)
|
||||
@@ -0,0 +1,208 @@
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:openVending')
|
||||
AddEventHandler(Config.InventoryPrefix .. ':client:openVending', function(Data)
|
||||
local Category = Data['category']
|
||||
TriggerServerEvent('inventory:openVending', Category)
|
||||
end)
|
||||
|
||||
local spamCount = 0
|
||||
local lastSpamId = nil
|
||||
|
||||
local inventory_opening_anim = {
|
||||
-- dict = 'mp_player_inteat@burger',
|
||||
-- clip = 'mp_player_int_eat_burger_fp'
|
||||
}
|
||||
|
||||
local inventory_opening_disable = {
|
||||
move = true,
|
||||
car = true,
|
||||
mouse = true,
|
||||
combat = true
|
||||
}
|
||||
|
||||
local openingInv = false
|
||||
RegisterCommand('inventory', function()
|
||||
if inInventory then
|
||||
return Debug('Inventory is already open')
|
||||
end
|
||||
if Config.OpenProgressBar and openingInv then return end
|
||||
if IsNuiFocused() then return Debug('NUI Focused') end
|
||||
if spamCount > 2 then
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_SPAM'), 'error')
|
||||
return
|
||||
end
|
||||
spamCount = spamCount + 1
|
||||
lastSpamId = math.random(1, 999999)
|
||||
local spamId = lastSpamId
|
||||
SetTimeout(1000, function()
|
||||
if spamId == lastSpamId then
|
||||
spamCount = 0
|
||||
end
|
||||
end)
|
||||
if LocalPlayer.state.inv_busy or not CanUseInventory() then
|
||||
Warning("You can't use this action because inv_busy is active (avoids dupes)")
|
||||
return SendTextMessage(Lang('INVENTORY_NOTIFICATION_NOT_ACCESSIBLE'), 'error')
|
||||
end
|
||||
|
||||
if Config.OpenProgressBar then
|
||||
openingInv = true
|
||||
local success = ProgressBarSync('inventory', 'Inventory opening', 800, true, true, inventory_opening_disable, inventory_opening_anim)
|
||||
openingInv = false
|
||||
if not success then
|
||||
print('failed')
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if inInventory and not IsNuiFocused() then
|
||||
SetFocus(true)
|
||||
return
|
||||
end
|
||||
|
||||
if not isCrafting and not inInventory and not inventoryDisabled then
|
||||
if not IsPauseMenuActive() then
|
||||
local ped = PlayerPedId()
|
||||
local curVeh = nil
|
||||
local VendingMachine = nil
|
||||
local garbage = nil
|
||||
local CurrentGarbage = {}
|
||||
local entity, entityModel, data = GetNearbyGarbage()
|
||||
if entity then
|
||||
local x, y, z = table.unpack(GetEntityCoords(entity))
|
||||
local _, floorZ = GetGroundZFor_3dCoord(x, y, z, false)
|
||||
garbage = getOwnerFromCoordsForGarbage(vector3(x, y, floorZ))
|
||||
CurrentGarbage.label = data.label
|
||||
CurrentGarbage.items = data.items
|
||||
CurrentGarbage.slots = data.slots
|
||||
end
|
||||
|
||||
if not Config.UseTarget then
|
||||
VendingMachine = GetClosestVending()
|
||||
end
|
||||
|
||||
if IsPedInAnyVehicle(ped, false) then -- Is Player In Vehicle
|
||||
local vehicle = GetVehiclePedIsIn(ped, false)
|
||||
CurrentGlovebox = Trim(GetVehicleNumberPlateText(vehicle))
|
||||
curVeh = vehicle
|
||||
CurrentVehicle = nil
|
||||
else
|
||||
local vehicle = getClosestVehicle()
|
||||
if vehicle ~= 0 and vehicle ~= nil then
|
||||
local pos = GetEntityCoords(ped)
|
||||
local dimensionMin, dimensionMax = GetModelDimensions(GetEntityModel(vehicle))
|
||||
local trunkpos = GetOffsetFromEntityInWorldCoords(vehicle, 0.0, (dimensionMin.y), 0.0)
|
||||
if (IsBackEngine(GetEntityModel(vehicle))) then
|
||||
trunkpos = GetOffsetFromEntityInWorldCoords(vehicle, 0.0, (dimensionMax.y), 0.0)
|
||||
end
|
||||
if #(pos - trunkpos) < 1.5 and not IsPedInAnyVehicle(ped) then
|
||||
if GetVehicleDoorLockStatus(vehicle) < 2 then
|
||||
CurrentVehicle = Trim(GetVehicleNumberPlateText(vehicle))
|
||||
curVeh = vehicle
|
||||
CurrentGlovebox = nil
|
||||
else
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_VEHICLE_LOCKED'), 'error')
|
||||
return
|
||||
end
|
||||
else
|
||||
CurrentVehicle = nil
|
||||
end
|
||||
else
|
||||
CurrentVehicle = nil
|
||||
end
|
||||
end
|
||||
|
||||
if CurrentVehicle then -- Trunk
|
||||
local vehicleClass = GetVehicleClass(curVeh)
|
||||
Debug('Current vehicleClass of the vehicle that is being unlocked:', vehicleClass)
|
||||
local maxweight = Config.VehicleClass[vehicleClass].trunk.maxweight or 60000
|
||||
local slots = Config.VehicleClass[vehicleClass].trunk.slots or 35
|
||||
local isCustomVehicle = Config.CustomTrunk[GetEntityModel(curVeh)]
|
||||
|
||||
if isCustomVehicle then
|
||||
maxweight = isCustomVehicle.maxweight
|
||||
slots = isCustomVehicle.slots
|
||||
end
|
||||
|
||||
local other = {
|
||||
maxweight = maxweight,
|
||||
slots = slots,
|
||||
}
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'trunk', CurrentVehicle, other)
|
||||
OpenTrunk()
|
||||
elseif CurrentGlovebox then
|
||||
local vehicleClass = GetVehicleClass(curVeh)
|
||||
Debug('Current vehicleClass of the vehicle that is being unlocked:', vehicleClass)
|
||||
local maxweight = Config.VehicleClass[vehicleClass].glovebox.maxweight or 60000
|
||||
local slots = Config.VehicleClass[vehicleClass].glovebox.slots or 35
|
||||
local isCustomVehicle = Config.CustomGlovebox[GetEntityModel(curVeh)]
|
||||
|
||||
if isCustomVehicle then
|
||||
maxweight = isCustomVehicle.maxweight
|
||||
slots = isCustomVehicle.slots
|
||||
end
|
||||
local other = {
|
||||
maxweight = maxweight,
|
||||
slots = slots
|
||||
}
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'glovebox', CurrentGlovebox, other)
|
||||
elseif CurrentDrop ~= 0 then
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'drop', CurrentDrop)
|
||||
elseif garbage then
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'garbage', garbage, CurrentGarbage, entityModel)
|
||||
OpenGarbage()
|
||||
elseif VendingMachine then
|
||||
local vendingCategory = nil
|
||||
local vendingModel = GetEntityModel(VendingMachine)
|
||||
for _, vendingData in pairs(Config.Vendings) do
|
||||
local vendingDataModel = GetHashKey(vendingData.Model)
|
||||
if vendingDataModel == vendingModel then
|
||||
vendingCategory = vendingData.Category
|
||||
break
|
||||
end
|
||||
end
|
||||
if vendingCategory then
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:openVending', { category = vendingCategory })
|
||||
end
|
||||
else
|
||||
OpenAnim()
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory')
|
||||
end
|
||||
end
|
||||
end
|
||||
end, false)
|
||||
|
||||
RegisterKeyMapping('inventory', Lang('INVENTORY_KEYMAPPING_OPEN_LABEL'), 'keyboard', Config.KeyBinds.inventory)
|
||||
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:OpenPlayerInventory')
|
||||
AddEventHandler(Config.InventoryPrefix .. ':client:OpenPlayerInventory', function()
|
||||
ExecuteCommand('inventory')
|
||||
end)
|
||||
|
||||
RegisterCommand('hotbar', function()
|
||||
if inventoryDisabled then return end
|
||||
if IsNuiFocused() then return end
|
||||
if LocalPlayer.state.inv_busy or not CanUseInventory() then
|
||||
Warning("You can't use this action because inv_busy is active (avoids dupes)")
|
||||
return
|
||||
end
|
||||
|
||||
isHotbar = not isHotbar
|
||||
if not IsPauseMenuActive() then
|
||||
ToggleHotbar(isHotbar)
|
||||
end
|
||||
end, false)
|
||||
|
||||
RegisterKeyMapping('hotbar', Lang('INVENTORY_KEYMAPPING_HOTBAR_LABEL'), 'keyboard', Config.KeyBinds.hotbar)
|
||||
|
||||
RegisterKeyMapping('reloadweapon', Lang('INVENTORY_KEYMAPPING_RELOAD_LABEL'), 'keyboard', Config.KeyBinds.reload)
|
||||
|
||||
RegisterCommand('reloadweapon', function()
|
||||
if not CurrentWeaponData?.name then return end
|
||||
local weaponData = WeaponList[joaat(CurrentWeaponData?.name)]
|
||||
if not weaponData then return end
|
||||
|
||||
if LocalPlayer.state.inv_busy or not CanUseInventory() then
|
||||
Debug("You can't use this action because inv_busy is active (avoids dupes)")
|
||||
return SendTextMessage(Lang('INVENTORY_NOTIFICATION_NOT_ACCESSIBLE'), 'error')
|
||||
end
|
||||
TriggerServerEvent('weapons:reloadWeapon', weaponData.ammotype)
|
||||
end, false)
|
||||
@@ -0,0 +1,41 @@
|
||||
local color = {} --[[@as Color]]
|
||||
|
||||
---@param data Color
|
||||
RegisterNUICallback('updateColors', function(data, cb)
|
||||
color.primaryColor = data.primaryColor or color.primaryColor
|
||||
color.primaryOpacity = data.primaryOpacity or color.primaryOpacity
|
||||
color.secondaryColor = data.secondaryColor or color.secondaryColor
|
||||
color.secondaryOpacity = data.secondaryOpacity or color.secondaryOpacity
|
||||
color.borderColor = data.borderColor or color.borderColor
|
||||
color.borderOpacity = data.borderOpacity or color.borderOpacity
|
||||
color.borderRadius = data.borderRadius or color.borderRadius
|
||||
|
||||
LocalPlayer.state:set('primaryColor', color.primaryColor, true)
|
||||
LocalPlayer.state:set('primaryOpacity', color.primaryOpacity, true)
|
||||
|
||||
TriggerEvent('inventory:updateColors', color)
|
||||
cb(true)
|
||||
end)
|
||||
|
||||
exports('getColors', function()
|
||||
return color
|
||||
end)
|
||||
|
||||
|
||||
local function handleThemeChange()
|
||||
local handler
|
||||
handler = AddEventHandler('inventory:updateColors', function()
|
||||
if not IsPlayerLoaded() then
|
||||
Debug('handleThemeChange', 'Player not loaded, skipping color update')
|
||||
return
|
||||
end
|
||||
|
||||
Debug('handleThemeChange', 'Theme color updated successfully')
|
||||
|
||||
RemoveEventHandler(handler)
|
||||
handler = nil
|
||||
end)
|
||||
end
|
||||
|
||||
handleThemeChange()
|
||||
TriggerEvent('inventory:updateColors')
|
||||
@@ -0,0 +1,41 @@
|
||||
if not GetResourceState('jobs_creator') == 'missing' then
|
||||
return
|
||||
end
|
||||
|
||||
Warning('Started the compatibility module with jobs_creator')
|
||||
|
||||
CreateThread(function()
|
||||
local other = {}
|
||||
other.maxweight = 100000 -- Custom weight stash.
|
||||
other.slots = 50 -- Custom slots spaces.
|
||||
|
||||
RegisterNetEvent('jobs_creator:stash:openStash', function(markerId)
|
||||
local stashId = 'job_stash_' .. markerId
|
||||
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'stash', stashId, other)
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:SetCurrentStash', stashId)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jobs_creator:safe:openSafe', function(markerId)
|
||||
local safeId = 'job_safe_' .. markerId
|
||||
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'stash', safeId, other)
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:SetCurrentStash', safeId)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jobs_creator:armory:openArmory', function(markerId)
|
||||
local armoryId = 'job_armory_' .. markerId
|
||||
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'stash', armoryId, other)
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:SetCurrentStash', armoryId)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jobs_creator:framework:ready', function()
|
||||
-- Disables the default script search (otherwise there would be 2 searches)
|
||||
exports['jobs_creator']:disableScriptEvent('jobs_creator:actions:search:searchPlayer')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jobs_creator:actions:search:searchPlayer', function(targetServerId)
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', targetServerId)
|
||||
end)
|
||||
end)
|
||||
@@ -0,0 +1,10 @@
|
||||
function JonskaItemThrow(item)
|
||||
local data = {
|
||||
name = item.name, -- needed for adding and removing item
|
||||
label = item.label, -- MUST HAVE!
|
||||
amount = item.amount, -- needed for adding and removing item
|
||||
info = item.info, -- needed for adding item
|
||||
created = item.created or 0 -- needed for adding item (if your inventory have decay system)
|
||||
}
|
||||
return exports['jonska-itemthrowing']:throwItem(data, item.name, item.amount)
|
||||
end
|
||||
@@ -0,0 +1,190 @@
|
||||
if not Config.Handsup then
|
||||
return
|
||||
end
|
||||
|
||||
local lib, anim = 'missminuteman_1ig_2', 'handsup_base'
|
||||
local canHandsUp = true
|
||||
local deadPlayer = false
|
||||
|
||||
local function LoadAnimDict(dict)
|
||||
if HasAnimDictLoaded(dict) then return end
|
||||
|
||||
RequestAnimDict(dict)
|
||||
while not HasAnimDictLoaded(dict) do
|
||||
Wait(10)
|
||||
end
|
||||
end
|
||||
|
||||
RegisterKeyMapping('handsup', Lang('INVENTORY_KEYMAPPING_HANDSUP_LABEL'), 'keyboard', Config.KeyBinds.handsup)
|
||||
|
||||
RegisterCommand('handsup', function()
|
||||
if not IsPedInAnyVehicle(PlayerPedId(), false) and GetEntityHealth(PlayerPedId()) > 1 then
|
||||
RequestAnimDict(lib)
|
||||
while not HasAnimDictLoaded(lib) do
|
||||
Wait(100)
|
||||
end
|
||||
SetCurrentPedWeapon(PlayerPedId(), GetHashKey('WEAPON_UNARMED'), true)
|
||||
if IsEntityPlayingAnim(PlayerPedId(), lib, anim, 3) then
|
||||
ClearPedSecondaryTask(PlayerPedId())
|
||||
else
|
||||
if canHandsUp then
|
||||
TaskPlayAnim(PlayerPedId(), lib, anim, 2.0, 2.5, -1, 49, 0, 0, 0, 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:RobPlayer')
|
||||
AddEventHandler(Config.InventoryPrefix .. ':client:RobPlayer', function(TargetId)
|
||||
local ped = PlayerPedId()
|
||||
if IsPedArmed(ped, 1) or IsPedArmed(ped, 2) or IsPedArmed(ped, 4) or deadPlayer or Config.StealWithoutWeapons then
|
||||
SendNUIMessage({
|
||||
action = 'RobPlayer',
|
||||
TargetId = TargetId,
|
||||
})
|
||||
end
|
||||
deadPlayer = false
|
||||
end)
|
||||
|
||||
local function checkPlayerIsNear(targetPlayer)
|
||||
CreateThread(function()
|
||||
while true do
|
||||
Wait(100)
|
||||
local targetPed = GetPlayerPed(targetPlayer)
|
||||
|
||||
if not DoesEntityExist(targetPed) or NetworkIsPlayerActive(targetPlayer) == false then
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:closeinv')
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_ROBBERY_AWAY'), 'inform')
|
||||
break
|
||||
end
|
||||
|
||||
local playerCoords = GetEntityCoords(PlayerPedId())
|
||||
local targetCoords = GetEntityCoords(targetPed)
|
||||
local distance = #(playerCoords - targetCoords)
|
||||
|
||||
if distance > 5 then
|
||||
Wait(500)
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:closeinv')
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_ROBBERY_AWAY'), 'inform')
|
||||
break
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:search', function()
|
||||
local player, distance = GetClosestPlayer(GetEntityCoords(PlayerPedId()))
|
||||
if player ~= -1 and distance < 2.5 then
|
||||
local playerId = GetPlayerServerId(player)
|
||||
local searchPlayerPed = GetPlayerPed(player)
|
||||
if IsEntityPlayingAnim(searchPlayerPed, 'missminuteman_1ig_2', 'handsup_base', 3) or Config.StealDeadPlayer and checkEntityDead(playerId, searchPlayerPed) or GetEntityHealth(searchPlayerPed) <= 0 then
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', playerId)
|
||||
checkPlayerIsNear(player)
|
||||
inRobbery = true
|
||||
else
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_HANDSUP'), 'error')
|
||||
end
|
||||
else
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_PLAYERS'), 'error')
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent(Config.InventoryPrefix .. ':client:playerRobbery')
|
||||
AddEventHandler(Config.InventoryPrefix .. ':client:playerRobbery', function()
|
||||
local player, distance = GetClosestPlayer(GetEntityCoords(PlayerPedId()))
|
||||
if player ~= -1 and distance < 3.0 then
|
||||
local searchPlayerPed = GetPlayerPed(player)
|
||||
local playerId = GetPlayerServerId(player)
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:forceCloseInventory')
|
||||
Wait(500)
|
||||
|
||||
if checkEntityDead(playerId, searchPlayerPed) then
|
||||
RequestAnimDict('amb@world_human_gardener_plant@male@base')
|
||||
while not HasAnimDictLoaded('amb@world_human_gardener_plant@male@base') do
|
||||
Wait(100)
|
||||
end
|
||||
TaskPlayAnim(PlayerPedId(), 'amb@world_human_gardener_plant@male@base', 'base', 8.0, -8, -1, 1, 0, 0, 0, 0)
|
||||
ProgressBar('steal_playerdead', Lang('INVENTORY_PROGRESS_STEAL'), 5500, false, true, {
|
||||
move = true,
|
||||
car = true,
|
||||
mouse = false,
|
||||
combat = true,
|
||||
}, {}, {}, {}, function() -- Done
|
||||
TaskPlayAnim(PlayerPedId(), 'amb@world_human_gardener_plant@male@base', 'base', 8.0, -8, -1, 1, 0, 0, 0, 0)
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', playerId)
|
||||
checkPlayerIsNear(player)
|
||||
inRobbery = true
|
||||
end, function() -- Cancel
|
||||
ClearPedTasks(PlayerPedId())
|
||||
end)
|
||||
return
|
||||
end
|
||||
|
||||
if DoesEntityExist(searchPlayerPed) and IsEntityPlayingAnim(searchPlayerPed, lib, anim, 3) and not checkEntityDead(playerId, searchPlayerPed) then
|
||||
LoadAnimDict('combat@aim_variations@arrest')
|
||||
TaskPlayAnim(PlayerPedId(), 'combat@aim_variations@arrest', 'cop_med_arrest_01', 8.0, -8, -1, 1, 0, 0, 0, 0)
|
||||
ProgressBar('steal_player', Lang('INVENTORY_PROGRESS_STEAL'), 5500, false, true, {
|
||||
move = true,
|
||||
car = true,
|
||||
mouse = false,
|
||||
combat = true,
|
||||
}, {}, {}, {}, function() -- Done
|
||||
TaskPlayAnim(PlayerPedId(), 'combat@aim_variations@arrest', 'cop_med_arrest_01', 8.0, -8, -1, 1, 0, 0, 0, 0)
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', playerId)
|
||||
SetPedConfigFlag(PlayerPedId(), 36, true)
|
||||
checkPlayerIsNear(player)
|
||||
inRobbery = true
|
||||
end, function() -- Cancel
|
||||
ClearPedTasks(PlayerPedId())
|
||||
end)
|
||||
else
|
||||
SendTextMessage(Lang('INVENTORY_NOTIFICATION_NO_HANDSUP'), 'error')
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
function checkPlayerRobbery(other)
|
||||
if other and other.id then
|
||||
local target = tonumber(other.id)
|
||||
local playerTarget = GetPlayerFromServerId(target)
|
||||
local pedTarget = GetPlayerPed(playerTarget)
|
||||
if other ~= nil then
|
||||
currentOtherInventory = other.name
|
||||
end
|
||||
if target and DoesEntityExist(pedTarget) then
|
||||
local pos = GetEntityCoords(playerPed)
|
||||
local targetPos = GetEntityCoords(pedTarget)
|
||||
local distance = GetDistanceBetweenCoords(pos.x, pos.y, pos.z, targetPos.x, targetPos.y, targetPos.z, true)
|
||||
if distance < 3.0 then
|
||||
inInventory = true
|
||||
deadPlayer = true
|
||||
StealingPed = pedTarget
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:RobPlayer', target)
|
||||
end
|
||||
end
|
||||
else
|
||||
local closestPlayer, closestDistance = GetClosestPlayer(GetEntityCoords(PlayerPedId()))
|
||||
if closestPlayer and closestPlayer ~= -1 and closestDistance < 3.0 then
|
||||
local playerId = GetPlayerServerId(closestPlayer)
|
||||
local searchPlayerPed = GetPlayerPed(closestPlayer)
|
||||
if searchPlayerPed and searchPlayerPed ~= 0 then
|
||||
if Config.StealDeadPlayer and checkEntityDead(playerId, searchPlayerPed) then
|
||||
inInventory = true
|
||||
deadPlayer = true
|
||||
StealingPed = searchPlayerPed
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:RobPlayer', playerId)
|
||||
end
|
||||
if IsEntityPlayingAnim(searchPlayerPed, lib, anim, 3) then
|
||||
inInventory = true
|
||||
deadPlayer = false
|
||||
StealingPed = searchPlayerPed
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:RobPlayer', playerId)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
RegisterNetEvent('inventory:robClosestPlayer', function()
|
||||
checkPlayerRobbery()
|
||||
end)
|
||||
@@ -0,0 +1,7 @@
|
||||
local function exportHandler(exportName, func)
|
||||
AddEventHandler(('__cfx_export_qb-inventory_%s'):format(exportName), function(setCB)
|
||||
setCB(func)
|
||||
end)
|
||||
end
|
||||
|
||||
exportHandler('HasItem', HasItem)
|
||||
@@ -0,0 +1,122 @@
|
||||
if not Config.UseTarget then
|
||||
return
|
||||
end
|
||||
|
||||
local target_name = GetResourceState('ox_target'):find('started') and 'qtarget' or 'qb-target'
|
||||
|
||||
CreateThread(function()
|
||||
-- Selling
|
||||
for k, v in pairs(Config.SellItems) do
|
||||
exports[target_name]:AddBoxZone(k .. '_selling', vec3(v['coords'].x, v['coords'].y, v['coords'].z), 1.5, 1.5, {
|
||||
name = k .. '_selling',
|
||||
heading = 90.0,
|
||||
debugPoly = Config.ZoneDebug,
|
||||
minZ = v['coords'].z - 1,
|
||||
maxZ = v['coords'].z + 1,
|
||||
}, {
|
||||
options = {
|
||||
{
|
||||
type = 'client',
|
||||
icon = 'fa-solid fa-cash-register',
|
||||
label = Lang('INVENTORY_TEXT_SELLING'),
|
||||
canInteract = function(entity, distance, data)
|
||||
return true
|
||||
end,
|
||||
action = function(entity)
|
||||
local PawnshopItems = {}
|
||||
PawnshopItems.label = k
|
||||
PawnshopItems.items = v['items']
|
||||
PawnshopItems.slots = #v['items']
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'selling', 'itemselling_' .. k, PawnshopItems)
|
||||
end,
|
||||
},
|
||||
},
|
||||
distance = 2.5
|
||||
})
|
||||
end
|
||||
|
||||
-- Crafting
|
||||
if Config.Crafting then
|
||||
for k, v in pairs(Config.CraftingTables) do
|
||||
exports[target_name]:AddBoxZone(k .. '_crafting', vec3(v.location.x, v.location.y, v.location.z), 2.5, 2.5, {
|
||||
name = k .. '_crafting',
|
||||
heading = 90.0,
|
||||
debugPoly = Config.ZoneDebug,
|
||||
minZ = v.location.z - 1,
|
||||
maxZ = v.location.z + 1,
|
||||
}, {
|
||||
options = {
|
||||
{
|
||||
type = 'client',
|
||||
icon = 'fa-solid fa-hammer',
|
||||
label = 'Crafting',
|
||||
canInteract = function(entity, distance, data)
|
||||
return true
|
||||
end,
|
||||
action = function(entity)
|
||||
if isCrafting then return end
|
||||
if v.isjob then
|
||||
if IsPlayerAuthorized(v) then
|
||||
CurrentCrafting = k
|
||||
local crafting = {
|
||||
label = v.name,
|
||||
items = GeneralInfos(k)
|
||||
}
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'crafting', math.random(1, 99), crafting)
|
||||
end
|
||||
else
|
||||
CurrentCrafting = k
|
||||
local crafting = {
|
||||
label = v.name,
|
||||
items = GeneralInfos(k)
|
||||
}
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'crafting', math.random(1, 99), crafting)
|
||||
end
|
||||
end,
|
||||
},
|
||||
},
|
||||
distance = 2.5
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Vending shops
|
||||
if Config.Vendings then
|
||||
for k, v in pairs(Config.Vendings) do
|
||||
exports[target_name]:AddTargetModel(v['Model'], {
|
||||
options = {
|
||||
{
|
||||
icon = 'fa-solid fa-cash-register',
|
||||
label = 'Vending',
|
||||
action = function()
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:openVending', { category = v['Category'] })
|
||||
end
|
||||
},
|
||||
},
|
||||
distance = 2.5
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Gargabe Code
|
||||
exports[target_name]:AddTargetModel(Config.GarbageObjects, {
|
||||
options = {
|
||||
{
|
||||
icon = 'fa-solid fa-trash',
|
||||
label = 'Open Garbage',
|
||||
action = function()
|
||||
ExecuteCommand('inventory')
|
||||
end
|
||||
},
|
||||
},
|
||||
distance = 1.0
|
||||
})
|
||||
end)
|
||||
|
||||
function AddTargetEntity(entity, options, distance)
|
||||
distance = distance or 5.0
|
||||
exports[target_name]:AddTargetEntity(entity, {
|
||||
options = options,
|
||||
distance = distance
|
||||
})
|
||||
end
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
if not Config.Debug then
|
||||
return
|
||||
end
|
||||
|
||||
Debug('Debug Command', 'inventory:openStash command initialized')
|
||||
RegisterCommand('inventory:openStash', function(source, args)
|
||||
local id = args[1] or source
|
||||
local stashId = 'inventory_debug_stash' .. id
|
||||
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'stash', stashId)
|
||||
TriggerEvent(Config.InventoryPrefix .. ':client:SetCurrentStash', stashId)
|
||||
end)
|
||||
|
||||
Debug('Debug Command', 'inventory:search command initialized')
|
||||
RegisterCommand('inventory:search', function(source, args)
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', tonumber(args[1]))
|
||||
end)
|
||||
|
||||
Debug('Debug Command', 'inventory:openOther command initialized')
|
||||
RegisterCommand('inventory:openOther', function(source, args, raw)
|
||||
local target = tonumber(args[1])
|
||||
if not target then
|
||||
Debug('Debug Command', 'Invalid target ID')
|
||||
return
|
||||
end
|
||||
|
||||
TriggerServerEvent(Config.InventoryPrefix .. ':server:OpenInventory', 'otherplayer', target)
|
||||
end)
|
||||
TriggerEvent('chat:addSuggestion', '/inventory:openOther', 'Open inventory of another player', {
|
||||
{ name = 'targetId', help = 'Target player ID' },
|
||||
})
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,37 @@
|
||||
TriggerEvent('chat:addSuggestion', '/giveitem', 'Administrative command to give items to another player', {
|
||||
{ name = 'id', help = 'Id of the player to whom the item will be delivered' },
|
||||
{ name = 'item', help = 'Name of the item to deliver' },
|
||||
{ name = 'amount', help = 'Quantity of the item, if it is a weapon it will be ammo' },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/giveweapon', 'Administrative command to give weapons to another player', {
|
||||
{ name = 'id', help = 'Id of the player to whom the weapon will be delivered' },
|
||||
{ name = 'weapon', help = 'Name of the weapon to deliver' },
|
||||
{ name = 'ammo', help = 'Amount of ammo for the weapon' },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/resetinv', 'Administrative command to reset an inventory, it will not delete it', {
|
||||
{ name = 'type', help = 'Type of inventory to reset, example: [stash], [trunk], [glovebox]' },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/clearinv', 'Administrative command to remove all items of a certain player', {
|
||||
{ name = 'id', help = 'Enter the id of the player whose inventory you want to empty' },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/repairweapon', 'Administrative command to repair certain players weapons', {
|
||||
{ name = 'id', help = 'Select the id of the player to repair his weapon' },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/openinventorytarget', 'Administrative command to check the inventory of a target player', {
|
||||
{ name = 'id', help = 'Select player id' },
|
||||
})
|
||||
|
||||
TriggerEvent('chat:addSuggestion', '/inventory', 'Command to open the inventory, useful for keybinds', {})
|
||||
TriggerEvent('chat:addSuggestion', '/hotbar', 'Command to open the hotbar inventory, useful for keybinds', {})
|
||||
TriggerEvent('chat:addSuggestion', '/handsup', 'Command to raise your arms, useful for keybinds, if you have your arms raised they can steal you', {})
|
||||
TriggerEvent('chat:addSuggestion', '/reloadweapon', 'Command to reload your weapon, useful for keybinds', {})
|
||||
TriggerEvent('chat:addSuggestion', '/randomitems', 'Administrative command that delivers various random items to your inventory, helps with debugging', {})
|
||||
TriggerEvent('chat:addSuggestion', '/searchplayer', 'Command to steal from a nearby player, although we recommend doing it with the NUI raising his hands', {})
|
||||
TriggerEvent('chat:addSuggestion', '/rob', 'Exclusive qb command to steal players, used for police job frequently', {})
|
||||
TriggerEvent('chat:addSuggestion', '/invitems', 'Example of code used for getInventory, it will return all the items in your inventory', {})
|
||||
TriggerEvent('chat:addSuggestion', '/dataitem', 'Example command to give an item with customizable and automatic metadata', {})
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,426 @@
|
||||
local PlayerData = GetPlayerData()
|
||||
local CanShoot, MultiplierAmount = true, 0
|
||||
CurrentWeaponData = {}
|
||||
|
||||
local weaponTrackingActive = false
|
||||
|
||||
exports('GetCurrentWeapon', function()
|
||||
return CurrentWeaponData
|
||||
end)
|
||||
|
||||
lib.callback.register('weapons:client:GetCurrentWeapon', function()
|
||||
return CurrentWeaponData
|
||||
end)
|
||||
|
||||
local function SyncWeaponToServer()
|
||||
if not CurrentWeaponData or not CurrentWeaponData.info or not CurrentWeaponData.name then return end
|
||||
|
||||
local ammo = CurrentWeaponData.info.ammo or 0
|
||||
|
||||
TriggerServerEvent('weapons:server:UpdateWeaponAmmo', CurrentWeaponData, ammo)
|
||||
|
||||
if MultiplierAmount > 0 then
|
||||
TriggerServerEvent('weapons:server:UpdateWeaponQuality', CurrentWeaponData, MultiplierAmount, ammo)
|
||||
MultiplierAmount = 0
|
||||
end
|
||||
end
|
||||
|
||||
local function StartWeaponTracking()
|
||||
if weaponTrackingActive then return end
|
||||
weaponTrackingActive = true
|
||||
|
||||
CreateThread(function()
|
||||
while weaponTrackingActive and CurrentWeaponData and next(CurrentWeaponData) do
|
||||
local ped = PlayerPedId()
|
||||
local weapon = GetSelectedPedWeapon(ped)
|
||||
|
||||
if weapon ~= `WEAPON_UNARMED` and CurrentWeaponData.info then
|
||||
CurrentWeaponData.info.ammo = GetAmmoInPedWeapon(ped, weapon)
|
||||
end
|
||||
|
||||
if IsPedShooting(ped) then
|
||||
if CanShoot then
|
||||
if weapon and weapon ~= 0 and WeaponList[weapon] then
|
||||
MultiplierAmount = MultiplierAmount + 1
|
||||
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
|
||||
Wait(100)
|
||||
end
|
||||
weaponTrackingActive = false
|
||||
end)
|
||||
end
|
||||
|
||||
local function StopWeaponTracking()
|
||||
weaponTrackingActive = false
|
||||
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 CurrentWeaponData and next(CurrentWeaponData) then
|
||||
SyncWeaponToServer()
|
||||
StopWeaponTracking()
|
||||
end
|
||||
|
||||
if data ~= false and data ~= nil then
|
||||
CurrentWeaponData = data
|
||||
CanShoot = bool
|
||||
StartWeaponTracking()
|
||||
else
|
||||
CurrentWeaponData = {}
|
||||
CanShoot = bool
|
||||
end
|
||||
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 total > 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 total > 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)
|
||||
|
||||
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)
|
||||
Reference in New Issue
Block a user