--- Citizen.CreateThread(function() while GetResourceState('kq_link') == 'stopped' do print('^6[KQ_LINK MISSING] ^1kq_link is required but not running! Make sure that you\'ve got it installed and started before ' .. GetCurrentResourceName()) print('^6 View the INSTALLATION.md file to find kq_link^0') Citizen.Wait(1000) end local function OnItemUse(player, item) TriggerClientEvent('kq_roofboxes:client:place', player, item) end for type, item in pairs(Config.items) do exports.kq_link:RegisterUsableItem(item, function(source) OnItemUse(source, item) end) end -- OX Inventory solution exports('UseRoofbox', function(event, item, inventory) if event == 'usingItem' then local player = inventory.id OnItemUse(player, item.name) return true end end) end) --- function GetVehicleIdentifier(vehicle) if not DoesEntityExist(vehicle) then return nil end -- You could replace this with your custom solution for getting the vehicles return GetVehicleNumberPlateText(vehicle) .. '-' .. GetEntityModel(vehicle) end function GetVehicleStashId(vehicle) return GetVehicleIdentifier(vehicle) .. '-roofbox' end function CanPlayerModifyRoofboxForVehicle(player, vehicle) local distance = #(GetEntityCoords(GetPlayerPed(player)) - GetEntityCoords(vehicle)) if distance > 6 then return false -- Players can not modify the roofbox from more than 6 meters away from the vehicle end -- You may add your own logic in this function to define who can modify(add or delete) the roofboxes return true end function CanPlayerRemoveVehicleRoofbox(player, vehicle) local stashId = GetVehicleStashId(vehicle) local stashItems = exports.kq_link:GetStashItems(stashId) if (stashItems and table.length(stashItems or {}) > 0) then TriggerClientEvent('kq_link:client:notify', player, L('The roofbox is not empty'), 'error') return false end return true end function CanPlayerOpenVehicleRoofbox(player, vehicle) local distance = #(GetEntityCoords(GetPlayerPed(player)) - GetEntityCoords(vehicle)) if distance > 5 then return false -- Players can not open the roofbox from more than 5 meters away from the vehicle end -- You may add your own logic in this function to define who can modify(add or delete) the roofboxes return true end --- SQL Stuff local SQL_DRIVER = Config.sql.driver local function SqlQuery(query, data) if SQL_DRIVER == 'mysql' then return MySQL.Sync.fetchAll(query, data or {}) end if SQL_DRIVER == 'oxmysql' then if Config.sql.newOxMysql then return exports[SQL_DRIVER]:fetchSync(query, data or {}) end return exports[SQL_DRIVER]:query_async(query, data or {}) else return exports[SQL_DRIVER]:executeSync(query, data or {}) end end local function SqlMutate(query, data) if SQL_DRIVER == 'mysql' then MySQL.Sync.insert(query, data) return end if SQL_DRIVER == 'oxmysql' then exports[SQL_DRIVER]:insertSync(query, data) else exports[SQL_DRIVER]:executeSync(query, data) end end DB = { FetchRoofboxesFromDatabase = function() local query = 'SELECT * FROM kq_roofboxes' return SqlQuery(query) end, SaveVehicleRoofbox = function(vehicle, roofboxData) local identifier = GetVehicleIdentifier(vehicle) local mutation = 'INSERT INTO kq_roofboxes (`identifier`, `data`) VALUES(@identifier, @data);' local data = { ['@identifier'] = identifier, ['@data'] = json.encode(roofboxData), } SqlMutate(mutation, data) end, DeleteVehicleRoofbox = function(vehicle) local identifier = GetVehicleIdentifier(vehicle) local mutation = 'DELETE FROM kq_roofboxes WHERE `identifier` = @identifier;' local data = { ['@identifier'] = identifier, } SqlMutate(mutation, data) end, } DB.SqlMutate = SqlMutate DB.SqlQuery = SqlQuery