structura foldere
mutat kq- folders in un singur folder [kq]
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
if not Config.Debug then return end
|
||||
|
||||
Debug('`gizmo` debug command initialized')
|
||||
RegisterCommand('gizmo', function(source, args, raw)
|
||||
currentlyInGarage = 'Pillbox Hill Garage'
|
||||
decorate:open()
|
||||
end)
|
||||
+213
@@ -0,0 +1,213 @@
|
||||
if Config.Framework ~= 'esx' then
|
||||
return
|
||||
end
|
||||
|
||||
ESX = exports['es_extended']:getSharedObject()
|
||||
|
||||
RegisterNetEvent('esx:playerLoaded')
|
||||
AddEventHandler('esx:playerLoaded', function(playerData)
|
||||
PlayerData = playerData
|
||||
Debug('player loaded', json.encode(playerData))
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
PlayerData = GetPlayerData()
|
||||
Debug('init playerData')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('esx:setJob', function(jobData)
|
||||
PlayerData.job = jobData
|
||||
end)
|
||||
|
||||
function TriggerServerCallback(name, cb, ...)
|
||||
ESX.TriggerServerCallback(name, cb, ...)
|
||||
end
|
||||
|
||||
function GetPlayerData()
|
||||
return ESX.GetPlayerData()
|
||||
end
|
||||
|
||||
function GetPlayers()
|
||||
return ESX.Game.GetPlayers()
|
||||
end
|
||||
|
||||
function GetPlayerIdentifier()
|
||||
return GetPlayerData().identifier
|
||||
end
|
||||
|
||||
function GetJobName()
|
||||
return PlayerData?.job?.name or 'unemployed'
|
||||
end
|
||||
|
||||
function GetJobGrade()
|
||||
return PlayerData?.job?.grade or 0
|
||||
end
|
||||
|
||||
local hasGang = GetResourceState('qs-gangs') == 'started'
|
||||
|
||||
Gang = nil
|
||||
|
||||
if hasGang then
|
||||
RegisterNetEvent('gangs:setGang', function(gang)
|
||||
Gang = gang
|
||||
end)
|
||||
end
|
||||
|
||||
function GetGang()
|
||||
if not hasGang then
|
||||
return {
|
||||
name = '',
|
||||
grades = {}
|
||||
}
|
||||
end
|
||||
if Gang then
|
||||
return Gang
|
||||
end
|
||||
local gang = exports['qs-gangs']:GetGang()
|
||||
Gang = gang
|
||||
if not gang then
|
||||
return {
|
||||
name = '',
|
||||
grades = {}
|
||||
}
|
||||
end
|
||||
return gang
|
||||
end
|
||||
|
||||
function DrawMarkerZone(x, y, z)
|
||||
DrawMarker(1, x, y, z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 4.0, 0.8, 255, 255, 255, 150, false, false, false, true, false, false, false)
|
||||
end
|
||||
|
||||
function SpawnGiveVehicle(model, generatedPlate, playerID, playerName, vehicleType, addcommand)
|
||||
local playerPed = cache.ped
|
||||
local coords = GetEntityCoords(playerPed)
|
||||
|
||||
ESX.Game.SpawnVehicle(model, coords, 0.0, function(vehicle)
|
||||
if DoesEntityExist(vehicle) then
|
||||
local carExist = true
|
||||
SetEntityVisible(vehicle, false)
|
||||
SetEntityCollision(vehicle, false)
|
||||
|
||||
local newPlate = generatedPlate
|
||||
local vehicleProps = ESX.Game.GetVehicleProperties(vehicle)
|
||||
vehicleProps.plate = newPlate
|
||||
TriggerServerEvent('advancedgarages:server:setVehicle', vehicleProps, model, playerID, vehicleType, addcommand)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function SpawnVehicleEvents(vehicle, plate)
|
||||
if GetResourceState(Config.Framework .. '-wheelstancer') == 'started' then
|
||||
-- You can ignore this, it only works with tuff-wheelstancer
|
||||
TriggerServerCallback('advancedgarages:server:GetStanceValues', function(stance_value)
|
||||
if stance_value ~= nil then
|
||||
Wait(500)
|
||||
local veh = cache.vehicle
|
||||
TriggerServerEvent('Stancer_sv:LoadStanceValues', stance_value, VehToNet(veh))
|
||||
end
|
||||
end, plate)
|
||||
end
|
||||
-- You can add your events here when the vehicle spawns
|
||||
end
|
||||
|
||||
function GetVehiclePropertiesFramework(vehicle)
|
||||
return ESX.Game.GetVehicleProperties(vehicle)
|
||||
end
|
||||
|
||||
function SetVehiclePropertiesFramework(vehicle, props)
|
||||
ESX.Game.SetVehicleProperties(vehicle, props)
|
||||
end
|
||||
|
||||
function ToggleHud(show)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
exports['qs-interface']:ToggleHud(show)
|
||||
end
|
||||
end
|
||||
|
||||
function Notification(msg, type)
|
||||
SendReactMessage('notification', {
|
||||
msg = msg,
|
||||
type = type
|
||||
})
|
||||
-- if GetResourceState('qs-interface') == 'started' then
|
||||
-- if type == 'info' then
|
||||
-- exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas 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 == 'info' then
|
||||
-- lib.notify({
|
||||
-- title = 'Garages',
|
||||
-- description = msg,
|
||||
-- type = 'info'
|
||||
-- })
|
||||
-- elseif type == 'error' then
|
||||
-- lib.notify({
|
||||
-- title = 'Garages',
|
||||
-- description = msg,
|
||||
-- type = 'error'
|
||||
-- })
|
||||
-- elseif type == 'success' then
|
||||
-- lib.notify({
|
||||
-- title = 'Garages',
|
||||
-- description = msg,
|
||||
-- type = 'success'
|
||||
-- })
|
||||
-- end
|
||||
end
|
||||
|
||||
function ShowHelpNotification(msg, thisFrame, beep, duration)
|
||||
AddTextEntry('HelpNotification', msg)
|
||||
|
||||
if thisFrame then
|
||||
DisplayHelpTextThisFrame('HelpNotification', false)
|
||||
else
|
||||
if beep == nil then
|
||||
beep = true
|
||||
end
|
||||
BeginTextCommandDisplayHelp('HelpNotification')
|
||||
EndTextCommandDisplayHelp(0, false, beep, duration or -1)
|
||||
end
|
||||
end
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key, theme)
|
||||
local _id = key
|
||||
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)
|
||||
Debug('Created text', id)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key, theme)
|
||||
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
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
if Config.Framework ~= 'qb' then
|
||||
return
|
||||
end
|
||||
|
||||
QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded')
|
||||
AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
|
||||
PlayerData = GetPlayerData()
|
||||
end)
|
||||
|
||||
RegisterNetEvent('QBCore:Client:OnJobUpdate', function(jobData)
|
||||
PlayerData.job = jobData
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
PlayerData = GetPlayerData()
|
||||
end)
|
||||
|
||||
function TriggerServerCallback(name, cb, ...)
|
||||
QBCore.Functions.TriggerCallback(name, cb, ...)
|
||||
end
|
||||
|
||||
function GetPlayerData()
|
||||
return QBCore.Functions.GetPlayerData()
|
||||
end
|
||||
|
||||
function GetPlayers()
|
||||
return QBCore.Functions.GetPlayers()
|
||||
end
|
||||
|
||||
function GetPlayerIdentifier()
|
||||
return GetPlayerData().citizenid
|
||||
end
|
||||
|
||||
function GetJobName()
|
||||
return PlayerData?.job?.name or 'unemployed'
|
||||
end
|
||||
|
||||
function GetJobGrade()
|
||||
return PlayerData?.job?.grade?.level or 0
|
||||
end
|
||||
|
||||
local hasGang = GetResourceState('qs-gangs') == 'started'
|
||||
Gang = nil
|
||||
|
||||
if hasGang then
|
||||
RegisterNetEvent('gangs:setGang', function(gang)
|
||||
Gang = gang
|
||||
end)
|
||||
end
|
||||
|
||||
function GetGang()
|
||||
if not hasGang then
|
||||
return {
|
||||
name = '',
|
||||
grades = {}
|
||||
}
|
||||
end
|
||||
if Gang then
|
||||
return Gang
|
||||
end
|
||||
local gang = exports['qs-gangs']:GetGang()
|
||||
Gang = gang
|
||||
if not gang then
|
||||
return {
|
||||
name = '',
|
||||
grades = {}
|
||||
}
|
||||
end
|
||||
return gang
|
||||
end
|
||||
|
||||
function DrawMarkerZone(x, y, z)
|
||||
DrawMarker(1, x, y, z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 4.0, 0.8, 255, 255, 255, 150, false, false, false, true, false, false, false)
|
||||
end
|
||||
|
||||
function SpawnGiveVehicle(model, generatedPlate, playerID, playerName, vehicleType, addcommand)
|
||||
QBCore.Functions.SpawnVehicle(model, function(vehicle)
|
||||
if DoesEntityExist(vehicle) then
|
||||
local carExist = true
|
||||
SetEntityVisible(vehicle, false)
|
||||
SetEntityCollision(vehicle, false)
|
||||
|
||||
local newPlate = generatedPlate
|
||||
local vehicleProps = QBCore.Functions.GetVehicleProperties(vehicle)
|
||||
vehicleProps.plate = newPlate
|
||||
TriggerServerEvent('advancedgarages:server:setVehicle', vehicleProps, model, playerID, vehicleType, addcommand)
|
||||
end
|
||||
end, coords, true)
|
||||
end
|
||||
|
||||
function SpawnVehicleEvents(vehicle, plate)
|
||||
if GetResourceState(Config.Framework .. '-wheelstancer') == 'started' then
|
||||
-- You can ignore this, it only works with tuff-wheelstancer
|
||||
TriggerServerCallback('advancedgarages:server:GetStanceValues', function(stance_value)
|
||||
if stance_value ~= nil then
|
||||
Wait(500)
|
||||
local veh = cache.vehicle
|
||||
TriggerServerEvent('Stancer_sv:LoadStanceValues', stance_value, VehToNet(veh))
|
||||
end
|
||||
end, plate)
|
||||
end
|
||||
-- You can add your events here when the vehicle spawns
|
||||
end
|
||||
|
||||
function GetVehiclePropertiesFramework(vehicle)
|
||||
return QBCore.Functions.GetVehicleProperties(vehicle)
|
||||
end
|
||||
|
||||
function SetVehiclePropertiesFramework(vehicle, props)
|
||||
QBCore.Functions.SetVehicleProperties(vehicle, props)
|
||||
end
|
||||
|
||||
function ToggleHud(show)
|
||||
if GetResourceState('qs-interface') == 'started' then
|
||||
exports['qs-interface']:ToggleHud(show)
|
||||
end
|
||||
end
|
||||
|
||||
function Notification(msg, type)
|
||||
SendReactMessage('notification', {
|
||||
msg = msg,
|
||||
type = type
|
||||
})
|
||||
-- if GetResourceState('qs-interface') == 'started' then
|
||||
-- if type == 'info' then
|
||||
-- exports['qs-interface']:AddNotify(msg, 'Inform', 2500, 'fas 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 == 'info' then
|
||||
-- lib.notify({
|
||||
-- title = 'Garages',
|
||||
-- description = msg,
|
||||
-- type = 'info'
|
||||
-- })
|
||||
-- elseif type == 'error' then
|
||||
-- lib.notify({
|
||||
-- title = 'Garages',
|
||||
-- description = msg,
|
||||
-- type = 'error'
|
||||
-- })
|
||||
-- elseif type == 'success' then
|
||||
-- lib.notify({
|
||||
-- title = 'Garages',
|
||||
-- description = msg,
|
||||
-- type = 'success'
|
||||
-- })
|
||||
-- end
|
||||
end
|
||||
|
||||
function ShowHelpNotification(msg, thisFrame, beep, duration)
|
||||
AddTextEntry('HelpNotification', msg)
|
||||
|
||||
if thisFrame then
|
||||
DisplayHelpTextThisFrame('HelpNotification', false)
|
||||
else
|
||||
if beep == nil then
|
||||
beep = true
|
||||
end
|
||||
BeginTextCommandDisplayHelp('HelpNotification')
|
||||
EndTextCommandDisplayHelp(0, false, beep, duration or -1)
|
||||
end
|
||||
end
|
||||
|
||||
local texts = {}
|
||||
if GetResourceState('qs-textui') == 'started' then
|
||||
function DrawText3D(x, y, z, text, id, key, theme)
|
||||
local _id = key
|
||||
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)
|
||||
Debug('Created text', id)
|
||||
TriggerEvent('textui:DrawText3D', x, y, z, text, id, key, theme)
|
||||
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
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'BigDaddy-Fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['BigDaddy-Fuel']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['BigDaddy-Fuel']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'LegacyFuel' then
|
||||
return 100.0
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['LegacyFuel']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['LegacyFuel']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'cdn-fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['cdn-fuel']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['cdn-fuel']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'esx-sna-fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['esx-sna-fuel']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['esx-sna-fuel']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'lc_fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports["lc_fuel"]:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports["lc_fuel"]:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'lj-fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['lj-fuel']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['lj-fuel']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'okokGasStation' then
|
||||
return 100.0
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['okokGasStation']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['okokGasStation']:GetFuel(vehicle)
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Fuel ~= 'ox_fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
Entity(vehicle).state.fuel = fuelLevel
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return Entity(vehicle).state.fuel
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'ps-fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['ps-fuel']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['ps-fuel']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'qs-fuelstations' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['qs-fuelstations']:SetFuel(vehicle, fuelLevel)
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['qs-fuelstations']:GetFuel(vehicle)
|
||||
end
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
if Config.Fuel ~= 'ti_fuel' then
|
||||
return
|
||||
end
|
||||
|
||||
function SetFuel(vehicle, fuelLevel)
|
||||
local success, error = pcall(function()
|
||||
exports['ti_fuel']:setFuel(vehicle, fuelLevel, 'RON91')
|
||||
end)
|
||||
|
||||
if not success then
|
||||
Debug('You did not configure your fuel system and it is set to 100.0 in fuel, check in Config.Fuel')
|
||||
return 100.0
|
||||
end
|
||||
end
|
||||
|
||||
function GetFuel(vehicle)
|
||||
return exports['ti_fuel']:getFuel(vehicle)
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Inventory ~= 'inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
local maxweight = data.maxweight or 10000
|
||||
TriggerEvent('inventory:openInventory', { type = 'stash', id = uniq, title = 'Stash_' .. uniq, weight = maxweight, delay = 100, save = true })
|
||||
end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
if Config.Inventory ~= 'codem-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = tostring(uniq or 'garage'):gsub('-', '_')
|
||||
local name = 'stash_' .. uniq
|
||||
local maxweight = data.maxweight or 10000
|
||||
local slots = data.slots or 30
|
||||
|
||||
print('[INFO] Open stash CodeM:', name, 'MaxWeight:', maxweight, 'Slots:', slots)
|
||||
TriggerServerEvent('codem-inventory:server:openstash', name, slots, maxweight, name)
|
||||
end
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
if Config.Inventory ~= 'core_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
TriggerServerEvent('core_inventory:server:openInventory', tostring(uniq):gsub(':', ''):gsub('#', ''):gsub(' ', ''), 'stash', nil, nil)
|
||||
end
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
if Config.Inventory ~= 'origen_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
TriggerServerEvent('inventory:server:OpenInventory', 'stash', 'stash_house' .. uniq .. '', data)
|
||||
end
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
if Config.Inventory ~= 'ox_inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
local ox_inventory = exports.ox_inventory
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
uniq = uniq:gsub('-', '_')
|
||||
local maxweight = data.maxweight or 10000
|
||||
local slot = data.slots or 30
|
||||
if ox_inventory:openInventory('stash', uniq) == false then
|
||||
TriggerServerEvent('garages:ox:registerStash', uniq, slot, maxweight)
|
||||
ox_inventory:openInventory('stash', uniq)
|
||||
Debug('Ox Stash', 'Registering new stash', uniq)
|
||||
end
|
||||
end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
if Config.Inventory ~= 'ps-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
TriggerServerEvent('inventory:server:OpenInventory', 'stash', uniq, data)
|
||||
TriggerEvent('inventory:client:SetCurrentStash', uniq)
|
||||
end
|
||||
|
||||
RegisterNetEvent('inventory:client:SetCurrentStash', function(stash)
|
||||
CurrentStash = stash
|
||||
end)
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
if Config.Inventory ~= 'qb-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
-- if you use old qb-inventory version, uncomment here and remove 'housing:openStash' trigger.
|
||||
-- TriggerServerEvent('inventory:server:OpenInventory', 'stash', uniq, data)
|
||||
-- TriggerEvent('inventory:client:SetCurrentStash', uniq)
|
||||
TriggerServerEvent('garages:openStash', uniq, data)
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Inventory ~= 'qs-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
TriggerServerEvent('inventory:server:OpenInventory', 'stash', uniq, data)
|
||||
TriggerEvent('inventory:client:SetCurrentStash', uniq)
|
||||
end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
if Config.Inventory ~= 'tgiann-inventory' then
|
||||
return
|
||||
end
|
||||
|
||||
function openStash(customData, uniq)
|
||||
local data = customData or Config.DefaultStashData
|
||||
uniq = uniq or currentlyInGarage
|
||||
uniq = uniq:gsub('-', '_')
|
||||
local maxweight = data.maxweight or 10000
|
||||
exports['tgiann-inventory']:OpenInventory('stash', uniq, {
|
||||
maxweight = maxweight,
|
||||
slots = data.slots or 100,
|
||||
})
|
||||
end
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
if Config.Menu ~= 'esx_context' then
|
||||
return
|
||||
end
|
||||
|
||||
function OpenManagementMenu()
|
||||
local Elements = {
|
||||
{
|
||||
unselectable = true,
|
||||
title = 'Management',
|
||||
},
|
||||
{
|
||||
title = 'Give Key',
|
||||
name = 'givekey',
|
||||
},
|
||||
{
|
||||
title = 'Key Holders',
|
||||
name = 'keyholders',
|
||||
},
|
||||
{
|
||||
title = 'Sell Garage',
|
||||
name = 'sell',
|
||||
},
|
||||
}
|
||||
|
||||
ESX.OpenContext('right', Elements,
|
||||
function(menu, element)
|
||||
if element.name == 'givekey' then
|
||||
TriggerEvent('advancedgarages:openGiveKeyMenu')
|
||||
ESX.CloseContext()
|
||||
end
|
||||
if element.name == 'keyholders' then
|
||||
TriggerEvent('advancedgarages:openKeyHoldersMenu')
|
||||
ESX.CloseContext()
|
||||
end
|
||||
if element.name == 'sell' then
|
||||
TriggerEvent('advancedgarages:sellGarage')
|
||||
ESX.CloseContext()
|
||||
end
|
||||
end, function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
end
|
||||
|
||||
function openGiveKeyMenu(vehicleList)
|
||||
local Elements = {}
|
||||
table.insert(Elements, {
|
||||
unselectable = true,
|
||||
title = 'Give Key',
|
||||
})
|
||||
|
||||
for k, v in pairs(vehicleList) do
|
||||
table.insert(Elements, {
|
||||
title = 'Player: ' .. v.name.firstName .. ' ' .. v.name.lastName,
|
||||
name = 'givekey',
|
||||
data = {
|
||||
id = v.id,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.OpenContext('right', Elements, function(menu, element)
|
||||
if element.name == 'givekey' then
|
||||
local selectedData = element.data
|
||||
local data = {
|
||||
id = selectedData.id,
|
||||
garage = selectedData.garage
|
||||
}
|
||||
TriggerServerEvent('advancedgarages:giveKey', data)
|
||||
ESX.CloseContext()
|
||||
end
|
||||
end,
|
||||
function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
end
|
||||
|
||||
function openTakeKeyMenu()
|
||||
local Elements = {}
|
||||
local holders = lib.callback.await('advancedgarages:getGarageKeyHolders', false, ClosestGarage)
|
||||
if not holders or #holders == 0 then
|
||||
Notification(i18n.t('keyholders.empty_list'), 'info')
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(Elements, {
|
||||
unselectable = true,
|
||||
title = 'Take Key',
|
||||
})
|
||||
|
||||
for k, v in pairs(holders) do
|
||||
table.insert(Elements, {
|
||||
title = 'Player: ' .. v.firstname .. ' ' .. v.lastname,
|
||||
name = 'keyholders',
|
||||
data = {
|
||||
id = v.identifier,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.OpenContext('right', Elements, function(menu, element)
|
||||
if element.name == 'keyholders' then
|
||||
local selectedData = element.data
|
||||
local data = {
|
||||
id = selectedData.id,
|
||||
garage = selectedData.garage
|
||||
}
|
||||
TriggerServerEvent('advancedgarages:takeKey', data)
|
||||
ESX.CloseContext()
|
||||
end
|
||||
end,
|
||||
function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
end
|
||||
|
||||
function HandleKeyboard(callback)
|
||||
local Elements = {
|
||||
{
|
||||
title = 'Set a Price',
|
||||
input = true,
|
||||
inputType = 'number',
|
||||
inputValue = 1,
|
||||
inputPlaceholder = 'Garage Price...',
|
||||
name = 'price',
|
||||
},
|
||||
{
|
||||
title = 'Continue',
|
||||
name = 'next',
|
||||
},
|
||||
}
|
||||
ESX.OpenContext('right', Elements, function(menu, element)
|
||||
local amount = menu.eles[1].inputValue
|
||||
if amount == 0 or amount == nil then return end
|
||||
if element.name == 'next' then
|
||||
ESX.CloseContext()
|
||||
callback(amount)
|
||||
end
|
||||
end, function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
end
|
||||
|
||||
function HandleGarageJob()
|
||||
local promise = promise.new()
|
||||
local Elements = {
|
||||
{
|
||||
title = 'Job Name (you can leave it blank for everyone)',
|
||||
input = true,
|
||||
inputType = 'text',
|
||||
inputValue = '',
|
||||
inputPlaceholder = 'Job Name...',
|
||||
name = 'Job Name',
|
||||
},
|
||||
{
|
||||
title = 'Continue',
|
||||
name = 'next',
|
||||
},
|
||||
}
|
||||
|
||||
ESX.OpenContext('right', Elements, function(menu, element)
|
||||
local jobName = menu.eles[1].inputValue
|
||||
if jobName == nil then
|
||||
return promise:resolve(false)
|
||||
end
|
||||
if element.name == 'next' then
|
||||
ESX.CloseContext()
|
||||
promise:resolve(jobName)
|
||||
end
|
||||
end, function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
return Citizen.Await(promise)
|
||||
end
|
||||
|
||||
function OpenRecoveryMenu(vehicleList)
|
||||
local Elements = {}
|
||||
table.insert(Elements, {
|
||||
unselectable = true,
|
||||
title = 'Recovery Vehicle (OUT)',
|
||||
})
|
||||
|
||||
for k, v in pairs(vehicleList) do
|
||||
table.insert(Elements, {
|
||||
title = v.plate,
|
||||
plate = v.plate,
|
||||
type = v.type,
|
||||
name = 'recovery',
|
||||
data = {
|
||||
plate = v.plate,
|
||||
type = v.type
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.OpenContext('right', Elements, function(menu, element)
|
||||
if element.name == 'recovery' then
|
||||
local selectedData = element.data
|
||||
TriggerServerEvent('advancedgarages:RecoveryVehicle', selectedData)
|
||||
ESX.CloseContext()
|
||||
end
|
||||
end,
|
||||
function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
end
|
||||
|
||||
function OpenDeleteJobVehicleMenu(garage, job)
|
||||
local Elements = {}
|
||||
local vehicles = lib.callback.await('advancedgarages:getJobVehicles', false, garage, job)
|
||||
if not vehicles or #vehicles == 0 then
|
||||
Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(Elements, {
|
||||
unselectable = true,
|
||||
title = 'Delete work vehicles',
|
||||
})
|
||||
|
||||
|
||||
for k, v in pairs(vehicles) do
|
||||
table.insert(Elements, {
|
||||
title = v.plate,
|
||||
name = 'next',
|
||||
data = {
|
||||
plate = v.plate,
|
||||
garage = garage
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.OpenContext('right', Elements, function(menu, element)
|
||||
if element.name == 'next' then
|
||||
local selectedData = element.data
|
||||
TriggerServerEvent('advancedgarages:deleteJobVehicle', selectedData)
|
||||
ESX.CloseContext()
|
||||
end
|
||||
end, function(menu)
|
||||
ESX.CloseContext()
|
||||
end)
|
||||
end
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
if Config.Menu ~= 'esx_menu_default' then
|
||||
return
|
||||
end
|
||||
|
||||
function OpenManagementMenu()
|
||||
local elementsList = {}
|
||||
|
||||
table.insert(elementsList, { label = 'Give Key', value = 'givekey' })
|
||||
table.insert(elementsList, { label = 'Key Holders', value = 'keyholders' })
|
||||
table.insert(elementsList, { label = 'Sell Garage', value = 'sell' })
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'management', {
|
||||
title = 'Management',
|
||||
align = 'right',
|
||||
elements = elementsList
|
||||
}, function(data, menu)
|
||||
if data.current.value == 'givekey' then
|
||||
menu.close()
|
||||
TriggerEvent('advancedgarages:openGiveKeyMenu')
|
||||
end
|
||||
if data.current.value == 'keyholders' then
|
||||
menu.close()
|
||||
TriggerEvent('advancedgarages:openKeyHoldersMenu')
|
||||
end
|
||||
if data.current.value == 'sell' then
|
||||
menu.close()
|
||||
TriggerEvent('advancedgarages:sellGarage')
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
|
||||
function openGiveKeyMenu(players)
|
||||
local elementsList = {}
|
||||
|
||||
for k, v in pairs(players) do
|
||||
table.insert(elementsList, {
|
||||
label = 'Player: ' .. v.name.firstName .. ' ' .. v.name.lastName,
|
||||
value = {
|
||||
id = v.id,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'givekey', {
|
||||
title = 'Give Key',
|
||||
align = 'right',
|
||||
elements = elementsList
|
||||
}, function(data, menu)
|
||||
if data.current.value then
|
||||
menu.close()
|
||||
local selectedData = data.current.value
|
||||
local data = {
|
||||
id = selectedData.id,
|
||||
garage = selectedData.garage
|
||||
}
|
||||
TriggerServerEvent('advancedgarages:giveKey', data)
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
|
||||
function openTakeKeyMenu()
|
||||
local elementsList = {}
|
||||
local holders = lib.callback.await('advancedgarages:getGarageKeyHolders', false, ClosestGarage)
|
||||
if not holders or #holders == 0 then
|
||||
Notification(i18n.t('keyholders.empty_list'), 'info')
|
||||
return
|
||||
end
|
||||
for k, v in pairs(holders) do
|
||||
table.insert(elementsList, {
|
||||
label = 'Player: ' .. v.firstname .. ' ' .. v.lastname,
|
||||
value = {
|
||||
id = v.identifier,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'keyholders', {
|
||||
title = 'Recovery',
|
||||
align = 'right',
|
||||
elements = elementsList
|
||||
}, function(data, menu)
|
||||
if data.current.value then
|
||||
menu.close()
|
||||
local selectedData = data.current.value
|
||||
local data = {
|
||||
id = selectedData.id,
|
||||
garage = selectedData.garage
|
||||
}
|
||||
TriggerServerEvent('advancedgarages:takeKey', data)
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
|
||||
function HandleKeyboard(callback)
|
||||
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'price',
|
||||
{
|
||||
title = ('Set a price')
|
||||
},
|
||||
function(data, menu)
|
||||
local amount = tonumber(data.value)
|
||||
if amount == nil then
|
||||
Notification('Invalid Amount', 'error')
|
||||
else
|
||||
menu.close()
|
||||
callback(amount)
|
||||
end
|
||||
end,
|
||||
function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
|
||||
function HandleGarageJob()
|
||||
local promise = promise.new()
|
||||
ESX.UI.Menu.Open('dialog', GetCurrentResourceName(), 'job',
|
||||
{
|
||||
title = ('Job Name (you can leave it blank for everyone)')
|
||||
},
|
||||
function(data, menu)
|
||||
local jobName = data.value
|
||||
if jobName == nil then
|
||||
menu.close()
|
||||
return promise:resolve(false)
|
||||
end
|
||||
|
||||
promise:resolve(jobName)
|
||||
menu.close()
|
||||
end,
|
||||
function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
return Citizen.Await(promise)
|
||||
end
|
||||
|
||||
function OpenRecoveryMenu(vehicleList)
|
||||
local elementsList = {}
|
||||
|
||||
for k, v in pairs(vehicleList) do
|
||||
table.insert(elementsList, {
|
||||
label = v.plate,
|
||||
type = v.type,
|
||||
value = {
|
||||
plate = v.plate,
|
||||
type = v.type
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'recovery', {
|
||||
title = 'Recovery Vehicle (OUT)',
|
||||
align = 'right',
|
||||
elements = elementsList
|
||||
}, function(data, menu)
|
||||
if data.current.value then
|
||||
menu.close()
|
||||
local selectedData = data.current.value
|
||||
TriggerServerEvent('advancedgarages:RecoveryVehicle', selectedData)
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
|
||||
function OpenDeleteJobVehicleMenu(garage, job)
|
||||
local elementsList = {}
|
||||
local vehicles = lib.callback.await('advancedgarages:getJobVehicles', false, garage, job)
|
||||
if not vehicles or #vehicles == 0 then
|
||||
Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
return
|
||||
end
|
||||
|
||||
for k, v in pairs(vehicles) do
|
||||
table.insert(elementsList, {
|
||||
label = v.plate,
|
||||
value = {
|
||||
plate = v.plate,
|
||||
garage = garage
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'deletejob', {
|
||||
title = 'Delete work vehicles',
|
||||
align = 'right',
|
||||
elements = elementsList
|
||||
}, function(data, menu)
|
||||
local selectedData = data.current.value
|
||||
if selectedData then
|
||||
TriggerServerEvent('advancedgarages:deleteJobVehicle', selectedData)
|
||||
menu.close()
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
if Config.Menu ~= 'nh-context' then
|
||||
return
|
||||
end
|
||||
|
||||
function OpenManagementMenu()
|
||||
TriggerEvent('nh-context:createMenu', {
|
||||
{
|
||||
header = 'Management',
|
||||
},
|
||||
{
|
||||
header = 'Give Key',
|
||||
event = 'advancedgarages:openGiveKeyMenu',
|
||||
},
|
||||
{
|
||||
header = 'Key Holders',
|
||||
event = 'advancedgarages:openKeyHoldersMenu',
|
||||
},
|
||||
{
|
||||
header = 'Sell Garage',
|
||||
event = 'advancedgarages:sellGarage',
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
function openGiveKeyMenu(players)
|
||||
local Elements = {
|
||||
{
|
||||
header = 'Give Key',
|
||||
}
|
||||
}
|
||||
for k, v in pairs(players) do
|
||||
local data = {
|
||||
id = v.id,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
table.insert(Elements, {
|
||||
header = 'Give Key',
|
||||
context = 'Player: ' .. v.name.firstName .. ' ' .. v.name.lastName,
|
||||
event = 'advancedgarages:giveKey',
|
||||
server = true,
|
||||
args = {
|
||||
data
|
||||
}
|
||||
})
|
||||
end
|
||||
TriggerEvent('nh-context:createMenu', Elements)
|
||||
end
|
||||
|
||||
function openTakeKeyMenu()
|
||||
local Elements = {
|
||||
{
|
||||
header = 'Take Key',
|
||||
}
|
||||
}
|
||||
local holders = lib.callback.await('advancedgarages:getGarageKeyHolders', false, ClosestGarage)
|
||||
if not holders or #holders == 0 then
|
||||
Notification(i18n.t('keyholders.empty_list'), 'info')
|
||||
return
|
||||
end
|
||||
for k, v in pairs(holders) do
|
||||
local data = {
|
||||
id = v.identifier,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
table.insert(Elements, {
|
||||
header = 'Take Key',
|
||||
context = 'Player: ' .. v.firstname .. ' ' .. v.lastname,
|
||||
event = 'advancedgarages:takeKey',
|
||||
server = true,
|
||||
args = {
|
||||
data
|
||||
}
|
||||
})
|
||||
end
|
||||
TriggerEvent('nh-context:createMenu', Elements)
|
||||
end
|
||||
|
||||
function HandleKeyboard(callback)
|
||||
local keyboard, value = exports['nh-keyboard']:Keyboard({
|
||||
header = 'Set a Price',
|
||||
rows = { 'Price' }
|
||||
})
|
||||
if keyboard then
|
||||
callback(value)
|
||||
end
|
||||
end
|
||||
|
||||
function HandleGarageJob()
|
||||
local keyboard, value = exports['nh-keyboard']:Keyboard({
|
||||
header = 'Job Name (you can leave it blank for everyone)',
|
||||
rows = { 'Job Name' }
|
||||
})
|
||||
if keyboard then
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
function OpenRecoveryMenu(vehicleList)
|
||||
local menu = {}
|
||||
table.insert(menu, {
|
||||
header = 'Recovery Vehicle (OUT)'
|
||||
})
|
||||
for k, v in pairs(vehicleList) do
|
||||
table.insert(menu, {
|
||||
header = v.plate,
|
||||
event = 'advancedgarages:RecoveryVehicle',
|
||||
server = true,
|
||||
args = {
|
||||
v
|
||||
}
|
||||
})
|
||||
end
|
||||
TriggerEvent('nh-context:createMenu', menu)
|
||||
end
|
||||
|
||||
function OpenDeleteJobVehicleMenu(garage, job)
|
||||
local menu = {}
|
||||
local vehicles = lib.callback.await('advancedgarages:getJobVehicles', false, garage, job)
|
||||
|
||||
if not vehicles or #vehicles == 0 then
|
||||
Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(menu, {
|
||||
header = 'Delete work vehicles'
|
||||
})
|
||||
|
||||
for k, v in pairs(vehicles) do
|
||||
local data = {
|
||||
plate = v.plate,
|
||||
garage = garage
|
||||
}
|
||||
table.insert(menu, {
|
||||
header = v.plate,
|
||||
event = 'advancedgarages:deleteJobVehicle',
|
||||
server = true,
|
||||
args = {
|
||||
data
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
TriggerEvent('nh-context:createMenu', menu)
|
||||
end
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
if Config.Menu ~= 'ox_lib' then
|
||||
return
|
||||
end
|
||||
|
||||
function OpenManagementMenu()
|
||||
local elements = {
|
||||
{
|
||||
title = 'Give Key',
|
||||
onSelect = function(args)
|
||||
TriggerEvent('advancedgarages:openGiveKeyMenu')
|
||||
end
|
||||
},
|
||||
{
|
||||
title = 'Key Holders',
|
||||
onSelect = function(args)
|
||||
TriggerEvent('advancedgarages:openKeyHoldersMenu')
|
||||
end
|
||||
},
|
||||
{
|
||||
title = 'Sell Garage',
|
||||
onSelect = function(args)
|
||||
TriggerEvent('advancedgarages:sellGarage')
|
||||
end
|
||||
}
|
||||
}
|
||||
lib.registerContext({
|
||||
id = 'management',
|
||||
title = 'Management',
|
||||
options = elements
|
||||
})
|
||||
lib.showContext('management')
|
||||
end
|
||||
|
||||
function openGiveKeyMenu(players)
|
||||
local elements = {}
|
||||
for k, v in pairs(players) do
|
||||
table.insert(elements, {
|
||||
title = 'Player: ' .. v.name.firstName .. ' ' .. v.name.lastName,
|
||||
onSelect = function(args)
|
||||
local data = {
|
||||
id = v.id,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
TriggerServerEvent('advancedgarages:giveKey', data)
|
||||
end
|
||||
})
|
||||
end
|
||||
lib.registerContext({
|
||||
id = 'givekey',
|
||||
title = 'Give Keys',
|
||||
options = elements
|
||||
})
|
||||
lib.showContext('givekey')
|
||||
end
|
||||
|
||||
function openTakeKeyMenu()
|
||||
local elements = {}
|
||||
local holders = lib.callback.await('advancedgarages:getGarageKeyHolders', false, ClosestGarage)
|
||||
if not holders or #holders == 0 then
|
||||
Notification(i18n.t('keyholders.empty_list'), 'info')
|
||||
return
|
||||
end
|
||||
for k, v in pairs(holders) do
|
||||
table.insert(elements, {
|
||||
title = 'Player: ' .. v.firstname .. ' ' .. v.lastname,
|
||||
onSelect = function(args)
|
||||
local data = {
|
||||
id = v.identifier,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
TriggerServerEvent('advancedgarages:takeKey', data)
|
||||
end
|
||||
})
|
||||
end
|
||||
lib.registerContext({
|
||||
id = 'keyholders',
|
||||
title = 'Key Holders',
|
||||
options = elements
|
||||
})
|
||||
lib.showContext('keyholders')
|
||||
end
|
||||
|
||||
function HandleKeyboard(callback)
|
||||
local input = lib.inputDialog('Set a Price', { 'Garage Price...' })
|
||||
|
||||
if not input then return end
|
||||
local price = tonumber(input[1])
|
||||
|
||||
if price then
|
||||
local amount = price
|
||||
if amount == nil then
|
||||
Notification('Invalid Amount', 'error')
|
||||
else
|
||||
if amount >= 0 then
|
||||
callback(amount)
|
||||
else
|
||||
Notification('Invalid Amount', 'error')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function HandleGarageJob()
|
||||
local input = lib.inputDialog('Job Name (you can leave it blank for everyone)', { 'Job Name' })
|
||||
if not input or input[1] == '' then return false end
|
||||
return input[1]
|
||||
end
|
||||
|
||||
function OpenRecoveryMenu(vehicleList)
|
||||
local menu = {}
|
||||
for k, v in pairs(vehicleList) do
|
||||
table.insert(menu, {
|
||||
title = v.plate,
|
||||
onSelect = function(args)
|
||||
TriggerServerEvent('advancedgarages:RecoveryVehicle', { plate = v.plate, type = v.type })
|
||||
end,
|
||||
})
|
||||
end
|
||||
lib.registerContext({
|
||||
id = 'recovery',
|
||||
title = 'Recovery Vehicle (OUT)',
|
||||
options = menu
|
||||
})
|
||||
lib.showContext('recovery')
|
||||
end
|
||||
|
||||
function OpenDeleteJobVehicleMenu(garage, job)
|
||||
local menu = {}
|
||||
local vehicles = lib.callback.await('advancedgarages:getJobVehicles', false, garage, job)
|
||||
if not vehicles or #vehicles == 0 then
|
||||
Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
return
|
||||
end
|
||||
for k, v in pairs(vehicles) do
|
||||
local data = {
|
||||
plate = v.plate,
|
||||
garage = garage
|
||||
}
|
||||
table.insert(menu, {
|
||||
title = v.plate,
|
||||
onSelect = function(args)
|
||||
TriggerServerEvent('advancedgarages:deleteJobVehicle', data)
|
||||
end,
|
||||
})
|
||||
end
|
||||
lib.registerContext({
|
||||
id = 'deletejobvehicle',
|
||||
title = 'Delete work vehicles',
|
||||
options = menu
|
||||
})
|
||||
lib.showContext('deletejobvehicle')
|
||||
end
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
if Config.Menu ~= 'qb-menu' then
|
||||
return
|
||||
end
|
||||
|
||||
function OpenManagementMenu()
|
||||
local elementsList = {
|
||||
{
|
||||
header = 'Management',
|
||||
isMenuHeader = true,
|
||||
},
|
||||
{
|
||||
header = 'Give Key',
|
||||
params = {
|
||||
event = 'advancedgarages:openGiveKeyMenu',
|
||||
}
|
||||
},
|
||||
{
|
||||
header = 'Key Holders',
|
||||
params = {
|
||||
event = 'advancedgarages:openKeyHoldersMenu',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports['qb-menu']:openMenu(elementsList)
|
||||
end
|
||||
|
||||
function openGiveKeyMenu(players)
|
||||
local elementsList = {}
|
||||
table.insert(elementsList, {
|
||||
header = 'Give Key',
|
||||
isMenuHeader = true,
|
||||
})
|
||||
for k, v in pairs(players) do
|
||||
table.insert(elementsList, {
|
||||
header = 'Player: ' .. v.name.firstName .. ' ' .. v.name.lastName,
|
||||
params = {
|
||||
isServer = true,
|
||||
event = 'advancedgarages:giveKey',
|
||||
args = {
|
||||
id = v.id,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
exports['qb-menu']:openMenu(elementsList)
|
||||
end
|
||||
|
||||
function openTakeKeyMenu()
|
||||
local elementsList = {}
|
||||
local holders = lib.callback.await('advancedgarages:getGarageKeyHolders', false, ClosestGarage)
|
||||
if not holders or #holders == 0 then
|
||||
Notification(i18n.t('keyholders.empty_list'), 'info')
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(elementsList, {
|
||||
header = 'Take Key',
|
||||
isMenuHeader = true,
|
||||
})
|
||||
|
||||
for k, v in pairs(holders) do
|
||||
table.insert(elementsList, {
|
||||
header = 'Player: ' .. v.firstname .. ' ' .. v.lastname,
|
||||
params = {
|
||||
isServer = true,
|
||||
event = 'advancedgarages:takeKey',
|
||||
args = {
|
||||
id = v.identifier,
|
||||
garage = ClosestGarage
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
exports['qb-menu']:openMenu(elementsList)
|
||||
end
|
||||
|
||||
function HandleKeyboard(callback)
|
||||
local dialog = exports['qb-input']:ShowInput({
|
||||
header = 'Set a Price',
|
||||
submitText = 'Continue',
|
||||
inputs = {
|
||||
{
|
||||
text = 'Garage Price...',
|
||||
name = 'price',
|
||||
type = 'number',
|
||||
isRequired = true,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if dialog ~= nil then
|
||||
for k, v in pairs(dialog) do
|
||||
callback(v)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function HandleGarageJob()
|
||||
local dialog = exports['qb-input']:ShowInput({
|
||||
header = 'Job Name (you can leave it blank for everyone)',
|
||||
submitText = 'Continue',
|
||||
inputs = {
|
||||
{
|
||||
text = 'Job Name...',
|
||||
name = 'Job public garage',
|
||||
type = 'text',
|
||||
isRequired = false,
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if dialog ~= nil then
|
||||
for k, v in pairs(dialog) do
|
||||
if v and v ~= '' then
|
||||
return v
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function OpenRecoveryMenu(vehicleList)
|
||||
local elementsList = {}
|
||||
table.insert(elementsList, {
|
||||
header = 'Recovery Vehicle (OUT)',
|
||||
isMenuHeader = true,
|
||||
})
|
||||
|
||||
for k, v in pairs(vehicleList) do
|
||||
table.insert(elementsList, {
|
||||
header = v.plate,
|
||||
params = {
|
||||
isServer = true,
|
||||
event = 'advancedgarages:RecoveryVehicle',
|
||||
args = {
|
||||
plate = v.plate,
|
||||
type = v.type
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
exports['qb-menu']:openMenu(elementsList)
|
||||
end
|
||||
|
||||
function OpenDeleteJobVehicleMenu(garage, job)
|
||||
local menu = {}
|
||||
local vehicles = lib.callback.await('advancedgarages:getJobVehicles', false, garage, job)
|
||||
|
||||
if not vehicles or #vehicles == 0 then
|
||||
Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
return
|
||||
end
|
||||
|
||||
table.insert(menu, {
|
||||
header = 'Delete work vehicles'
|
||||
})
|
||||
|
||||
for k, v in pairs(vehicles) do
|
||||
table.insert(menu, {
|
||||
header = v.plate,
|
||||
params = {
|
||||
isServer = true,
|
||||
event = 'advancedgarages:deleteJobVehicle',
|
||||
args = {
|
||||
plate = v.plate,
|
||||
garage = garage
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
exports['qb-menu']:openMenu(menu)
|
||||
end
|
||||
+352
@@ -0,0 +1,352 @@
|
||||
if Config.UseTarget ~= 'ox_target' then
|
||||
return
|
||||
end
|
||||
|
||||
local function storeVehicleZone2()
|
||||
local id = exports.ox_target:addGlobalVehicle({
|
||||
{
|
||||
name = 'garages:storeVehicle',
|
||||
icon = 'fas fa-car',
|
||||
label = 'Store Vehicle',
|
||||
-- bones = { 'door_dside_f', 'seat_dside_f' },
|
||||
canInteract = function(entity, distance, coords, name)
|
||||
if IsNearbyJobGarage() then return true end
|
||||
if CurrentShellGarage then return false end
|
||||
local _garage = ClosestGarage
|
||||
if not _garage then
|
||||
return false
|
||||
end
|
||||
local garage = Config.Garages[_garage]
|
||||
if not CheckGarageAuthorization(garage.jobs, garage.gangs) then return end
|
||||
if not garage then
|
||||
return false
|
||||
end
|
||||
local distance = #(coords - vec3(garage.coords.spawnCoords.x, garage.coords.spawnCoords.y, garage.coords.spawnCoords.z))
|
||||
if distance > 50.0 then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
onSelect = function(data)
|
||||
local jobGarage = IsNearbyJobGarage()
|
||||
if jobGarage then
|
||||
StoreVehicle(jobGarage, true, data.entity)
|
||||
return
|
||||
end
|
||||
if CurrentShellGarage and existKey then
|
||||
nearbyGarageType = 'vehicle'
|
||||
StoreVehicle(CurrentShellGarage, false, data.entity)
|
||||
return
|
||||
end
|
||||
StoreVehicle(ClosestGarage, false, data.entity)
|
||||
end
|
||||
}
|
||||
})
|
||||
return id
|
||||
end
|
||||
|
||||
storeVehicleZone2()
|
||||
|
||||
local function storeVehicleZone(garage, garageName, isJob)
|
||||
local options = {
|
||||
{
|
||||
onSelect = function()
|
||||
if isJob then
|
||||
StoreVehicle(garage, isJob)
|
||||
return
|
||||
end
|
||||
StoreVehicle(ClosestGarage or garageName, isJob)
|
||||
end,
|
||||
canInteract = function()
|
||||
return (isJob and CheckGarageAuthorization(garage.jobs, garage.gangs) and cache.vehicle) or (not garage.isImpound and (IsGarageOwner or garage.available or IsKeyHolder) and cache.vehicle)
|
||||
end,
|
||||
distance = 150.0,
|
||||
icon = 'fas fa-car',
|
||||
label = 'Store Vehicle'
|
||||
}
|
||||
}
|
||||
local id = exports.ox_target:addBoxZone({
|
||||
coords = garage.coords.spawnCoords,
|
||||
distance = 150.0,
|
||||
rotation = 180.0,
|
||||
options = options,
|
||||
debug = Config.ZoneDebug
|
||||
})
|
||||
return id
|
||||
end
|
||||
|
||||
local boxZones = {}
|
||||
function InitZones()
|
||||
if #boxZones > 0 then
|
||||
for k, v in pairs(boxZones) do
|
||||
exports.ox_target:removeZone(v)
|
||||
end
|
||||
boxZones = {}
|
||||
end
|
||||
Wait(100)
|
||||
for k, garage in pairs(Config.Garages) do
|
||||
local options = {}
|
||||
if garage.type ~= 'plane' or garage.isImpound then
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
OpenGarageMenu(k, garage.isImpound, nil, garage.type == 'boat')
|
||||
end,
|
||||
canInteract = function()
|
||||
local job = CheckGarageAuthorization(garage.jobs, garage.gangs)
|
||||
return (IsGarageOwner or garage.available or IsKeyHolder) and job
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-car',
|
||||
label = 'Open Garage'
|
||||
})
|
||||
end
|
||||
if not garage.isImpound then
|
||||
local garageType = garage.type
|
||||
if garageType == 'vehicle' or garageType == 'plane' then
|
||||
if garageType == 'plane' or (garageType == 'vehicle' and (Config.EnablePublicInteriors or not garage.available)) then
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
GotoShellGarage(k, garage.coords.spawnCoords, garage.shell)
|
||||
end,
|
||||
canInteract = function()
|
||||
local job = CheckGarageAuthorization(garage.jobs, garage.gangs)
|
||||
return (IsGarageOwner or garage.available or IsKeyHolder) and job
|
||||
end,
|
||||
icon = 'fas fa-warehouse',
|
||||
label = 'Enter the Garage',
|
||||
distance = 5.0
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
if not garage.owner or garage.owner == '' and not garage.isImpound then
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
local price = garage.price
|
||||
TriggerServerEvent('advancedgarages:buyGarage', k, price)
|
||||
end,
|
||||
canInteract = function()
|
||||
local job = CheckGarageAuthorization(garage.jobs, garage.gangs)
|
||||
return job
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-store',
|
||||
label = 'Buy Garage',
|
||||
debug = true
|
||||
})
|
||||
end
|
||||
local id = exports.ox_target:addBoxZone({
|
||||
coords = garage.coords.menuCoords,
|
||||
distance = 5.5,
|
||||
rotation = 180.0,
|
||||
name = 'garage:' .. k,
|
||||
id = k,
|
||||
index = k,
|
||||
options = options,
|
||||
debug = Config.ZoneDebug,
|
||||
})
|
||||
table.insert(boxZones, id)
|
||||
local otherId = storeVehicleZone(garage, k, false)
|
||||
table.insert(boxZones, otherId)
|
||||
end
|
||||
end
|
||||
|
||||
local shellBoxes = {}
|
||||
function InitShellGarages()
|
||||
for k, v in pairs(shellBoxes) do
|
||||
exports.ox_target:removeZone(v)
|
||||
shellBoxes = {}
|
||||
end
|
||||
for k, garage in pairs(ShellGarages) do
|
||||
if not garage.takeVehicle or not garage.takeVehicle.x then goto continue end
|
||||
local options = {}
|
||||
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
local shell = garage?.shell
|
||||
nearbyGarageType = 'vehicle'
|
||||
GotoGarage(CurrentShellGarage, vec4(garage.takeVehicle.x, garage.takeVehicle.y, garage.takeVehicle.z, garage.takeVehicle.h), shell)
|
||||
end,
|
||||
distance = 5.0,
|
||||
canInteract = function()
|
||||
return CurrentShellGarage == k and existKey
|
||||
end,
|
||||
icon = 'fas fa-warehouse',
|
||||
label = 'Enter the garage'
|
||||
})
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
local shell = garage?.shell
|
||||
nearbyGarageType = 'vehicle'
|
||||
SaveVehicle(k, true)
|
||||
-- GotoGarage(k, vec4(garage.takeVehicle.x, garage.takeVehicle.y, garage.takeVehicle.z, garage.takeVehicle.h), shell?.shell)
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-car',
|
||||
label = 'Store Vehicle',
|
||||
canInteract = function()
|
||||
return CurrentShellGarage == k and existKey and cache.vehicle
|
||||
end,
|
||||
})
|
||||
local id = exports.ox_target:addBoxZone({
|
||||
coords = vec3(garage.takeVehicle.x, garage.takeVehicle.y, garage.takeVehicle.z),
|
||||
distance = 5.5,
|
||||
rotation = 180.0,
|
||||
name = 'shell-garage:' .. k,
|
||||
id = 'shell-' .. k,
|
||||
index = k,
|
||||
options = options,
|
||||
debug = Config.ZoneDebug,
|
||||
})
|
||||
shellBoxes[k] = id
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
for k, garage in pairs(Config.JobGarages) do
|
||||
local job = garage.job or garage.gang
|
||||
local options = {}
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
local serverVehicles = lib.callback.await('advancedgarages:getJobVehicles', false, garage.name, job)
|
||||
local vehicleList = serverVehicles
|
||||
local garageIsAvailable = lib.callback.await('advancedgarages:isGarageAvailable', false, k)
|
||||
if not garageIsAvailable then return Notification(i18n.t('garage_not_available'), 'error') end
|
||||
for _, veh in pairs(vehicleList) do
|
||||
veh.vehicle = json.encode(veh.vehicle)
|
||||
end
|
||||
for a, model in ipairs(garage.vehicles) do
|
||||
local plate = tostring(job .. math.random(111, 999))
|
||||
table.insert(vehicleList, {
|
||||
id = #vehicleList + 1,
|
||||
vehicle = json.encode({
|
||||
model = model,
|
||||
plate = plate
|
||||
}),
|
||||
plate = plate,
|
||||
})
|
||||
end
|
||||
TriggerServerEvent('advancedgarages:setInJobGarage', k, true)
|
||||
OpenGarageMenu(k, garage.isImpound, vehicleList)
|
||||
end,
|
||||
canInteract = function()
|
||||
return CheckJob(garage.job, garage.grade)
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-car',
|
||||
label = 'Open Garage'
|
||||
})
|
||||
exports.ox_target:addBoxZone({
|
||||
coords = garage.coords.menuCoords,
|
||||
distance = 5.5,
|
||||
rotation = 180.0,
|
||||
name = 'job-garage:' .. k,
|
||||
id = k,
|
||||
index = k,
|
||||
options = options,
|
||||
debug = Config.ZoneDebug,
|
||||
})
|
||||
storeVehicleZone(garage, k, true)
|
||||
end
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
for k, types in pairs(Config.VehicleShowRooms) do
|
||||
for a, v in pairs(types) do
|
||||
local options = {}
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
ExitGarage()
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-warehouse',
|
||||
label = 'Exit Garage'
|
||||
})
|
||||
exports.ox_target:addBoxZone({
|
||||
coords = vec3(v.entry.x, v.entry.y, v.entry.z),
|
||||
distance = 5.5,
|
||||
rotation = 180.0,
|
||||
name = 'exit-garage:' .. k,
|
||||
id = k,
|
||||
index = k,
|
||||
options = options,
|
||||
debug = Config.ZoneDebug,
|
||||
})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
---@param coords vector4
|
||||
function InitShellExit(coords)
|
||||
exports.ox_target:addBoxZone({
|
||||
coords = coords,
|
||||
distance = 5.5,
|
||||
rotation = 180.0,
|
||||
name = 'exit-shell-garage',
|
||||
id = 'exit-shell-garage',
|
||||
options = {
|
||||
{
|
||||
onSelect = function()
|
||||
ExitGarage()
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-warehouse',
|
||||
label = 'Exit Garage'
|
||||
}
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
function RemoveShellExit()
|
||||
exports.ox_target:removeZone('exit-shell-garage')
|
||||
end
|
||||
|
||||
CreateThread(function()
|
||||
for k, v in pairs(Config.Recovery.coords) do
|
||||
local options = {}
|
||||
table.insert(options, {
|
||||
onSelect = function()
|
||||
local vehicleList = lib.callback.await('advancedgarages:getRecoveryVehicles', false)
|
||||
if #vehicleList == 0 then
|
||||
return Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
end
|
||||
OpenRecoveryMenu(vehicleList)
|
||||
end,
|
||||
distance = 5.0,
|
||||
icon = 'fas fa-car-on',
|
||||
label = 'Recover vehicle $' .. Config.Recovery.price
|
||||
})
|
||||
exports.ox_target:addBoxZone({
|
||||
coords = v,
|
||||
size = vec3(2.0, 2.0, 2.0),
|
||||
rotation = 180.0,
|
||||
name = 'recovery-garage:' .. k,
|
||||
id = k,
|
||||
index = k,
|
||||
options = options,
|
||||
debug = Config.ZoneDebug,
|
||||
})
|
||||
end
|
||||
end)
|
||||
|
||||
CreateThread(function()
|
||||
local function checkMenu()
|
||||
local sleep = 500
|
||||
if not ClosestGarage then return sleep end
|
||||
local garage = Config.Garages[ClosestGarage]
|
||||
if not IsGarageOwner and not garage.available and not IsKeyHolder then return sleep end
|
||||
if not CheckGarageAuthorization(garage.jobs, garage.gangs) then return sleep end
|
||||
if garage.isImpound then return sleep end
|
||||
if cache.vehicle then
|
||||
sleep = 0
|
||||
DrawMarkerZone(garage.coords.spawnCoords.x, garage.coords.spawnCoords.y, garage.coords.spawnCoords.z)
|
||||
-- DrawMarker(1, garage.coords.spawnCoords.x, garage.coords.spawnCoords.y, garage.coords.spawnCoords.z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 4.0, 0.8, 255, 255, 255, 150, false, false, false, true, false, false, false)
|
||||
end
|
||||
return sleep
|
||||
end
|
||||
while true do
|
||||
local sleep = checkMenu()
|
||||
Wait(sleep)
|
||||
end
|
||||
end)
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
if Config.UseTarget ~= 'qb-radialmenu' then
|
||||
return
|
||||
end
|
||||
|
||||
local menuItems = {}
|
||||
|
||||
local function AddRadialOption()
|
||||
RemoveRadialOptions()
|
||||
local garage, garageJobName
|
||||
|
||||
if ClosestGarage then
|
||||
garage = Config.Garages[ClosestGarage]
|
||||
end
|
||||
|
||||
if garage then
|
||||
if not cache.vehicle and (garage.available or IsGarageOwner or IsKeyHolder) then
|
||||
if not CheckGarageAuthorization(garage.jobs, garage.gangs) then goto continue end
|
||||
if garage.type ~= 'plane' and not cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialOpenMenu',
|
||||
title = 'Open Garage',
|
||||
icon = 'car',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialOpenMenu',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
if garage.type == 'plane' or ((Config.EnablePublicInteriors or not garage.available) and garage.type ~= 'boat' and not garage.isImpound and not cache.vehicle) then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialEnterShell',
|
||||
title = 'Enter Garage',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialEnterShell',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
|
||||
if cache.vehicle and ClosestGarage and not garage.isImpound then
|
||||
if not CheckGarageAuthorization(garage.jobs, garage.gangs) then goto continue end
|
||||
table.insert(menuItems, {
|
||||
id = 'radialSaveVehicle',
|
||||
title = 'Store Vehicle',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialSaveVehicle',
|
||||
garage = ClosestGarage,
|
||||
shouldClose = true
|
||||
})
|
||||
::continue::
|
||||
end
|
||||
|
||||
local nearbyElevator = nearbyElevator()
|
||||
if nearbyElevator and nearbyElevator == 0 then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialExitShell',
|
||||
title = 'Exit',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialExitShell',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
local recover = checkMenu()
|
||||
if recover == 0 then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialRecoverVehicle',
|
||||
title = 'Recover',
|
||||
icon = 'car',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialRecoverVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
if IsGarageOwner and not cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialGarageManagement',
|
||||
title = 'Management',
|
||||
icon = 'bars-progress',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialGarageManagement',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
local nearbyHouseGarage = CheckNearbyGarage()
|
||||
if nearbyHouseGarage and nearbyHouseGarage == 0 and cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'save_vehicle',
|
||||
title = 'Store Vehicle',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialSaveHousingGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
if nearbyHouseGarage and nearbyHouseGarage == 0 and not cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'enter_garage_shell',
|
||||
title = 'Enter Garage',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialEnterHousingGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
local job = GetJobName()
|
||||
if IsJobAllowed(job, 'impound') and not cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialImpoundVehicle',
|
||||
title = 'Impound vehicle',
|
||||
icon = 'car-side',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialImpoundVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
local playerCoords = GetEntityCoords(cache.ped)
|
||||
for k, garage in pairs(Config.JobGarages) do
|
||||
local access = CheckJob(garage.job, garage.grade)
|
||||
if access then
|
||||
local dst = #(playerCoords - vec3(garage.coords.menuCoords.x, garage.coords.menuCoords.y, garage.coords.menuCoords.z))
|
||||
if dst < 15.0 and not cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialOpenJobGarage',
|
||||
title = 'Open Garage',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialOpenJobGarage',
|
||||
garage = k,
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
if dst < 15.0 and cache.vehicle then
|
||||
table.insert(menuItems, {
|
||||
id = 'radialSaveVehicle',
|
||||
title = 'Save Vehicle',
|
||||
icon = 'warehouse',
|
||||
type = 'client',
|
||||
event = 'advancedgarages:client:radialSaveVehicle',
|
||||
garage = k,
|
||||
isJob = true,
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, item in ipairs(menuItems) do
|
||||
item.id = exports['qb-radialmenu']:AddOption(item)
|
||||
end
|
||||
end
|
||||
|
||||
function RemoveRadialOptions()
|
||||
for _, item in ipairs(menuItems) do
|
||||
exports['qb-radialmenu']:RemoveOption(item.id)
|
||||
end
|
||||
menuItems = {}
|
||||
|
||||
Debug('The qb-radialmenu table has been cleaned!')
|
||||
end
|
||||
|
||||
RegisterNetEvent('qb-radialmenu:client:onRadialmenuOpen', function()
|
||||
AddRadialOption()
|
||||
end)
|
||||
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if (resourceName == 'qs-advancedgarages') then
|
||||
RemoveRadialOptions()
|
||||
end
|
||||
end)
|
||||
+483
@@ -0,0 +1,483 @@
|
||||
if Config.UseTarget ~= 'qs-radialmenu' then
|
||||
return
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- State
|
||||
-- ============================================================
|
||||
|
||||
local shellExitCoords = nil
|
||||
local nearestGarage = nil
|
||||
|
||||
-- ============================================================
|
||||
-- Self-contained proximity detection
|
||||
-- Maintains nearestGarage independently of the escrowed code,
|
||||
-- so garage items appear even when ClosestGarage is not set.
|
||||
-- ============================================================
|
||||
|
||||
CreateThread(function()
|
||||
while true do
|
||||
local playerCoords = GetEntityCoords(cache.ped)
|
||||
local closest, closestDist = nil, 10.0
|
||||
for k, g in pairs(Config.Garages) do
|
||||
if g.coords and g.coords.menuCoords then
|
||||
local mc = g.coords.menuCoords
|
||||
local d = #(playerCoords - vec3(mc.x, mc.y, mc.z))
|
||||
if d < closestDist then
|
||||
closest = k
|
||||
closestDist = d
|
||||
end
|
||||
end
|
||||
end
|
||||
nearestGarage = closest
|
||||
Wait(closest and 250 or 1000)
|
||||
end
|
||||
end)
|
||||
|
||||
local function getClosestGarage()
|
||||
return ClosestGarage or nearestGarage
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Lifecycle hooks (same interface as ox_target.lua)
|
||||
-- The escrowed code calls these at key moments.
|
||||
-- ============================================================
|
||||
|
||||
function InitZones() end
|
||||
|
||||
function InitShellGarages() end
|
||||
|
||||
---@param coords vector4
|
||||
function InitShellExit(coords)
|
||||
shellExitCoords = coords
|
||||
end
|
||||
|
||||
function RemoveShellExit()
|
||||
shellExitCoords = nil
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Provider: getRadialItems export
|
||||
-- Called synchronously by qs-radialmenu before building menu.
|
||||
-- Returns a plain table of items — no cross-resource closures.
|
||||
-- ============================================================
|
||||
|
||||
exports('getRadialItems', function()
|
||||
local items = {}
|
||||
local playerCoords = GetEntityCoords(cache.ped)
|
||||
|
||||
local garageName = getClosestGarage()
|
||||
local garage = garageName and Config.Garages[garageName] or nil
|
||||
|
||||
local authorized = false
|
||||
if garage then
|
||||
local jobOk = type(CheckGarageAuthorization) ~= 'function' or CheckGarageAuthorization(garage.jobs, garage.gangs)
|
||||
authorized = jobOk and (IsGarageOwner or garage.available or IsKeyHolder)
|
||||
end
|
||||
|
||||
-- ── 1. Open Garage (on foot, authorized)
|
||||
if garage and not cache.vehicle and authorized then
|
||||
if garage.type ~= 'plane' or garage.isImpound then
|
||||
table.insert(items, {
|
||||
id = 'radialOpenMenu',
|
||||
title = 'Open Garage',
|
||||
icon = 'Car',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:openGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 2. Enter Garage interior (on foot, authorized)
|
||||
if garage and not cache.vehicle and authorized and not garage.isImpound then
|
||||
local gt = garage.type
|
||||
if gt == 'plane' or (gt == 'vehicle' and (Config.EnablePublicInteriors or not garage.available)) then
|
||||
table.insert(items, {
|
||||
id = 'radialEnterShell',
|
||||
title = 'Enter Garage',
|
||||
icon = 'Warehouse',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:enterShell',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 3. Buy Garage (no owner, authorized)
|
||||
if garage and not garage.isImpound and (not garage.owner or garage.owner == '') then
|
||||
local jobOk = type(CheckGarageAuthorization) ~= 'function' or CheckGarageAuthorization(garage.jobs, garage.gangs)
|
||||
if jobOk then
|
||||
table.insert(items, {
|
||||
id = 'radialBuyGarage',
|
||||
title = 'Buy Garage',
|
||||
icon = 'Store',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:buyGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 4. Store Vehicle – regular garage (in vehicle)
|
||||
if cache.vehicle and not CurrentShellGarage then
|
||||
local canStore = false
|
||||
if type(IsNearbyJobGarage) == 'function' and IsNearbyJobGarage() then
|
||||
canStore = true
|
||||
elseif garage and not garage.isImpound and authorized then
|
||||
local sp = garage.coords.spawnCoords
|
||||
local dst = #(playerCoords - vec3(sp.x, sp.y, sp.z))
|
||||
if dst <= 50.0 then
|
||||
canStore = true
|
||||
end
|
||||
end
|
||||
if canStore then
|
||||
table.insert(items, {
|
||||
id = 'radialStoreVehicle',
|
||||
title = 'Store Vehicle',
|
||||
icon = 'Car',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:storeVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 5. Shell garage options
|
||||
if CurrentShellGarage and existKey then
|
||||
local shellData = type(ShellGarages) == 'table' and ShellGarages[CurrentShellGarage] or nil
|
||||
if shellData and shellData.takeVehicle and shellData.takeVehicle.x then
|
||||
if not cache.vehicle then
|
||||
table.insert(items, {
|
||||
id = 'radialEnterShellGarage',
|
||||
title = 'Enter Garage',
|
||||
icon = 'Warehouse',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:enterShellGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
else
|
||||
table.insert(items, {
|
||||
id = 'radialStoreShellVehicle',
|
||||
title = 'Store Vehicle',
|
||||
icon = 'Car',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:storeShellVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 6. Exit Garage (shell exit or VehicleShowRooms)
|
||||
local showExit = false
|
||||
if shellExitCoords then
|
||||
showExit = true
|
||||
end
|
||||
if not showExit and Config.VehicleShowRooms then
|
||||
for _, types in pairs(Config.VehicleShowRooms) do
|
||||
for _, v in pairs(types) do
|
||||
if v.entry and v.entry.x then
|
||||
local dst = #(playerCoords - vec3(v.entry.x, v.entry.y, v.entry.z))
|
||||
if dst <= 5.5 then
|
||||
showExit = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if showExit then break end
|
||||
end
|
||||
end
|
||||
if showExit then
|
||||
table.insert(items, {
|
||||
id = 'radialExitGarage',
|
||||
title = 'Exit',
|
||||
icon = 'DoorOpen',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:exitGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
-- ── 7. Recover Vehicle
|
||||
if Config.Recovery and Config.Recovery.coords then
|
||||
for _, v in pairs(Config.Recovery.coords) do
|
||||
local dst = #(playerCoords - vec3(v.x, v.y, v.z))
|
||||
if dst <= 5.0 then
|
||||
table.insert(items, {
|
||||
id = 'radialRecoverVehicle',
|
||||
title = 'Recover $' .. (Config.Recovery.price or 0),
|
||||
icon = 'Car',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:recoverVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 8. Garage Management (owner only, on foot)
|
||||
if IsGarageOwner and not cache.vehicle then
|
||||
table.insert(items, {
|
||||
id = 'radialGarageManagement',
|
||||
title = 'Management',
|
||||
icon = 'Settings',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:management',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
|
||||
-- ── 9. Impound Vehicle (allowed job, on foot)
|
||||
if not cache.vehicle then
|
||||
local job = type(GetJobName) == 'function' and GetJobName() or nil
|
||||
if job and type(IsJobAllowed) == 'function' and IsJobAllowed(job, 'impound') then
|
||||
table.insert(items, {
|
||||
id = 'radialImpoundVehicle',
|
||||
title = 'Impound Vehicle',
|
||||
icon = 'Car',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:impoundVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- ── 10. Job Garages
|
||||
if Config.JobGarages then
|
||||
for k, jGarage in pairs(Config.JobGarages) do
|
||||
local access = type(CheckJob) == 'function' and CheckJob(jGarage.job, jGarage.grade) or false
|
||||
if access then
|
||||
local mc = jGarage.coords.menuCoords
|
||||
local dst = #(playerCoords - vec3(mc.x, mc.y, mc.z))
|
||||
if dst <= 15.0 then
|
||||
if not cache.vehicle then
|
||||
table.insert(items, {
|
||||
id = 'radialOpenJobGarage_' .. k,
|
||||
title = 'Open Garage',
|
||||
icon = 'Warehouse',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:openJobGarage',
|
||||
shouldClose = true
|
||||
})
|
||||
else
|
||||
table.insert(items, {
|
||||
id = 'radialStoreJobVehicle_' .. k,
|
||||
title = 'Store Vehicle',
|
||||
icon = 'Warehouse',
|
||||
type = 'client',
|
||||
event = 'qs-radialmenu:garages:storeJobVehicle',
|
||||
shouldClose = true
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return items
|
||||
end)
|
||||
|
||||
-- ============================================================
|
||||
-- Register as an item provider once qs-radialmenu is ready
|
||||
-- ============================================================
|
||||
|
||||
CreateThread(function()
|
||||
local attempts = 0
|
||||
while attempts < 60 do
|
||||
local ok = pcall(function()
|
||||
exports['qs-radialmenu']:RegisterItemProvider(GetCurrentResourceName())
|
||||
end)
|
||||
if ok then return end
|
||||
attempts = attempts + 1
|
||||
Wait(500)
|
||||
end
|
||||
end)
|
||||
|
||||
-- ============================================================
|
||||
-- Bridge events — call escrowed functions directly
|
||||
-- (mirrors ox_target onSelect callbacks)
|
||||
-- Use getClosestGarage() so bridge events also benefit from
|
||||
-- the self-contained proximity fallback.
|
||||
-- ============================================================
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:openGarage', function()
|
||||
local gName = getClosestGarage()
|
||||
if not gName then return end
|
||||
local garage = Config.Garages[gName]
|
||||
if not garage then return end
|
||||
if type(OpenGarageMenu) == 'function' then
|
||||
OpenGarageMenu(gName, garage.isImpound, nil, garage.type == 'boat')
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:enterShell', function()
|
||||
local gName = getClosestGarage()
|
||||
if not gName then return end
|
||||
local garage = Config.Garages[gName]
|
||||
if not garage then return end
|
||||
if type(GotoShellGarage) == 'function' then
|
||||
GotoShellGarage(gName, garage.coords.spawnCoords, garage.shell)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:buyGarage', function()
|
||||
local gName = getClosestGarage()
|
||||
if not gName then return end
|
||||
local garage = Config.Garages[gName]
|
||||
if not garage then return end
|
||||
TriggerServerEvent('advancedgarages:buyGarage', gName, garage.price)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:storeVehicle', function()
|
||||
if type(StoreVehicle) ~= 'function' then return end
|
||||
local jobGarage = type(IsNearbyJobGarage) == 'function' and IsNearbyJobGarage() or nil
|
||||
if jobGarage then
|
||||
StoreVehicle(jobGarage, true, cache.vehicle)
|
||||
return
|
||||
end
|
||||
local gName = getClosestGarage()
|
||||
StoreVehicle(gName, false, cache.vehicle)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:enterShellGarage', function()
|
||||
if not CurrentShellGarage or not existKey then return end
|
||||
local shellData = type(ShellGarages) == 'table' and ShellGarages[CurrentShellGarage] or nil
|
||||
if not shellData or not shellData.takeVehicle then return end
|
||||
nearbyGarageType = 'vehicle'
|
||||
if type(GotoGarage) == 'function' then
|
||||
GotoGarage(CurrentShellGarage, vec4(shellData.takeVehicle.x, shellData.takeVehicle.y, shellData.takeVehicle.z, shellData.takeVehicle.h), shellData.shell)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:storeShellVehicle', function()
|
||||
if not CurrentShellGarage or not existKey then return end
|
||||
nearbyGarageType = 'vehicle'
|
||||
if type(SaveVehicle) == 'function' then
|
||||
SaveVehicle(CurrentShellGarage, true)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:exitGarage', function()
|
||||
if type(ExitGarage) == 'function' then
|
||||
ExitGarage()
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:recoverVehicle', function()
|
||||
local vehicleList = lib.callback.await('advancedgarages:getRecoveryVehicles', false)
|
||||
if not vehicleList or #vehicleList == 0 then
|
||||
if type(Notification) == 'function' then
|
||||
Notification(i18n.t('keyholders.empty_out'), 'info')
|
||||
end
|
||||
return
|
||||
end
|
||||
if type(OpenRecoveryMenu) == 'function' then
|
||||
OpenRecoveryMenu(vehicleList)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:management', function()
|
||||
TriggerEvent('advancedgarages:client:radialGarageManagement')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:impoundVehicle', function()
|
||||
TriggerEvent('advancedgarages:client:radialImpoundVehicle')
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:openJobGarage', function()
|
||||
if not Config.JobGarages then return end
|
||||
local playerCoords = GetEntityCoords(cache.ped)
|
||||
for k, jGarage in pairs(Config.JobGarages) do
|
||||
local access = type(CheckJob) == 'function' and CheckJob(jGarage.job, jGarage.grade) or false
|
||||
if access then
|
||||
local mc = jGarage.coords.menuCoords
|
||||
local dst = #(playerCoords - vec3(mc.x, mc.y, mc.z))
|
||||
if dst <= 15.0 then
|
||||
local job = jGarage.job or jGarage.gang
|
||||
local serverVehicles = lib.callback.await('advancedgarages:getJobVehicles', false, jGarage.name, job)
|
||||
local vehicleList = serverVehicles or {}
|
||||
local garageIsAvailable = lib.callback.await('advancedgarages:isGarageAvailable', false, k)
|
||||
if not garageIsAvailable then
|
||||
if type(Notification) == 'function' then Notification(i18n.t('garage_not_available'), 'error') end
|
||||
return
|
||||
end
|
||||
for _, veh in pairs(vehicleList) do
|
||||
veh.vehicle = json.encode(veh.vehicle)
|
||||
end
|
||||
if jGarage.vehicles then
|
||||
for _, model in ipairs(jGarage.vehicles) do
|
||||
local plate = tostring(job .. math.random(111, 999))
|
||||
table.insert(vehicleList, {
|
||||
id = #vehicleList + 1,
|
||||
vehicle = json.encode({ model = model, plate = plate }),
|
||||
plate = plate,
|
||||
})
|
||||
end
|
||||
end
|
||||
TriggerServerEvent('advancedgarages:setInJobGarage', k, true)
|
||||
if type(OpenGarageMenu) == 'function' then
|
||||
OpenGarageMenu(k, jGarage.isImpound, vehicleList)
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('qs-radialmenu:garages:storeJobVehicle', function()
|
||||
if not Config.JobGarages or type(StoreVehicle) ~= 'function' then return end
|
||||
local playerCoords = GetEntityCoords(cache.ped)
|
||||
for k, jGarage in pairs(Config.JobGarages) do
|
||||
local access = type(CheckJob) == 'function' and CheckJob(jGarage.job, jGarage.grade) or false
|
||||
if access then
|
||||
local mc = jGarage.coords.menuCoords
|
||||
local dst = #(playerCoords - vec3(mc.x, mc.y, mc.z))
|
||||
if dst <= 15.0 then
|
||||
StoreVehicle(jGarage, true)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- ============================================================
|
||||
-- Cleanup
|
||||
-- ============================================================
|
||||
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if resourceName == 'qs-advancedgarages' then
|
||||
pcall(function()
|
||||
exports['qs-radialmenu']:UnregisterItemProvider(GetCurrentResourceName())
|
||||
end)
|
||||
end
|
||||
end)
|
||||
|
||||
-- ============================================================
|
||||
-- Marker thread (mirrors ox_target lines 333-352)
|
||||
-- Uses getClosestGarage() for proximity fallback.
|
||||
-- ============================================================
|
||||
|
||||
CreateThread(function()
|
||||
local function checkStoreMarker()
|
||||
local sleep = 500
|
||||
local gName = getClosestGarage()
|
||||
if not gName then return sleep end
|
||||
local garage = Config.Garages[gName]
|
||||
if not garage then return sleep end
|
||||
if not IsGarageOwner and not garage.available and not IsKeyHolder then return sleep end
|
||||
if type(CheckGarageAuthorization) == 'function' and not CheckGarageAuthorization(garage.jobs, garage.gangs) then return sleep end
|
||||
if garage.isImpound then return sleep end
|
||||
if cache.vehicle then
|
||||
sleep = 0
|
||||
if type(DrawMarkerZone) == 'function' then
|
||||
DrawMarkerZone(garage.coords.spawnCoords.x, garage.coords.spawnCoords.y, garage.coords.spawnCoords.z)
|
||||
end
|
||||
end
|
||||
return sleep
|
||||
end
|
||||
while true do
|
||||
Wait(checkStoreMarker())
|
||||
end
|
||||
end)
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'F_RealCarKeysSystem' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
TriggerServerEvent('F_RealCarKeysSystem:generateVehicleKeys', plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'MrNewbVehicleKeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
exports.MrNewbVehicleKeys:GiveKeysByPlate(plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
exports.MrNewbVehicleKeys:RemoveKeysByPlate(plate)
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'fivecode_carkeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
DecorSetInt(vehicle, 'owner', GetPlayerServerId(PlayerId()))
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
if Config.Vehiclekeys ~= 'glfp10_carkeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
if not item then return end
|
||||
if type(vehicle) ~= 'string' then return end
|
||||
|
||||
local model = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))
|
||||
TriggerServerEvent('carkeys:server:buyKey', plate, model)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'jc_vehiclekeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
exports['jc_vehiclekeys']:GiveKeys(plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
exports['jc_vehiclekeys']:RemoveKeys(plate)
|
||||
end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
if Config.Vehiclekeys ~= 'mono_carkeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
if not item then return end
|
||||
if type(vehicle) ~= 'string' then return end
|
||||
TriggerServerEvent('mono_carkeys:CreateKey', plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
if type(vehicle) ~= 'string' then return end
|
||||
TriggerServerEvent('mono_carkeys:DeleteKey', 1, plate)
|
||||
end
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
if Config.Vehiclekeys ~= 'qb-vehiclekeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
Wait(100)
|
||||
TriggerEvent('vehiclekeys:client:SetOwner', plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
if Config.Vehiclekeys ~= 'qbx_vehiclekeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
Wait(100)
|
||||
TriggerServerEvent('qb-vehiclekeys:server:AcquireVehicleKeys', plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
if Config.Vehiclekeys ~= 'qs-vehiclekeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
if not item then
|
||||
return
|
||||
end
|
||||
exports['qs-vehiclekeys']:GiveKeys(plate, vehicle, item)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
exports['qs-vehiclekeys']:RemoveKeys(plate, vehicle)
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'ti_vehicleKeys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
exports['ti_vehicleKeys']:addTemporaryVehicle(plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'vehicles_keys' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
TriggerServerEvent('vehicles_keys:selfGiveVehicleKeys', plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
if Config.Vehiclekeys ~= 'wasabi_carlock' then
|
||||
return
|
||||
end
|
||||
|
||||
local givenKeys = {}
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
if not plate or plate == '' then
|
||||
print('[WARNING] Invalid plate, unable to give key.')
|
||||
return
|
||||
end
|
||||
|
||||
if givenKeys[plate] then
|
||||
print('[INFO] Key already given for: ' .. plate)
|
||||
return
|
||||
end
|
||||
|
||||
givenKeys[plate] = true
|
||||
print('[DEBUG] Giving key via wasabi_carlock for plate: ' .. plate)
|
||||
exports.wasabi_carlock:GiveKey(plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
if not plate or plate == '' then
|
||||
print('[WARNING] Invalid plate, unable to remove key.')
|
||||
return
|
||||
end
|
||||
|
||||
givenKeys[plate] = nil
|
||||
|
||||
print('[DEBUG] Removing key via wasabi_carlock for plate: ' .. plate)
|
||||
exports.wasabi_carlock:RemoveKey(plate)
|
||||
end
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
if Config.Vehiclekeys ~= 'xd_locksystem' then
|
||||
return
|
||||
end
|
||||
|
||||
function AddVehiclekeys(vehicle, plate, item)
|
||||
exports['xd_locksystem']:givePlayerKeys(plate)
|
||||
end
|
||||
|
||||
function RemoveVehiclekeys(vehicle, plate)
|
||||
return
|
||||
end
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
if Config.Wardrobe ~= 'ak47_clothing' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
exports['ak47_clothing']:openOutfit() -- if it doesn't work with this export use other event
|
||||
-- TriggerEvent('ak47_clothing:openOutfitMenu') -- Use this only if the first export doesn't work, depend of you'r version
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'codem-appearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('codem-apperance:OpenWardrobe')
|
||||
end
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
if Config.Wardrobe ~= 'default' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
if Config.Framework == 'qb' then
|
||||
return TriggerEvent('qb-clothing:client:openOutfitMenu')
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'room', {
|
||||
title = Lang('HOUSING_MENU_WARDROBE_DEFAULT_TITLE'),
|
||||
align = 'right',
|
||||
elements = {
|
||||
{ label = Lang('HOUSING_MENU_CLOTHES_MENU'), value = 'player_dressing' },
|
||||
{ label = Lang('HOUSING_MENU_DELETE_CLOTHES'), value = 'remove_cloth' }
|
||||
}
|
||||
}, function(data, menu)
|
||||
if data.current.value == 'player_dressing' then
|
||||
menu.close()
|
||||
TriggerServerCallback('qb-houses:server:getPlayerDressing', function(dressing)
|
||||
elements = {}
|
||||
|
||||
for i = 1, #dressing, 1 do
|
||||
table.insert(elements, {
|
||||
label = dressing[i],
|
||||
value = i
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'player_dressing',
|
||||
{
|
||||
title = Lang('HOUSING_MENU_WARDROBE_DEFAULT_TITLE'),
|
||||
align = 'right',
|
||||
elements = elements
|
||||
}, function(data2, menu2)
|
||||
TriggerEvent('skinchanger:getSkin', function(skin)
|
||||
TriggerServerCallback('qb-houses:server:getPlayerOutfit', function(clothes)
|
||||
TriggerEvent('skinchanger:loadClothes', skin, clothes)
|
||||
TriggerEvent('esx_skin:setLastSkin', skin)
|
||||
|
||||
TriggerEvent('skinchanger:getSkin', function(skin)
|
||||
TriggerServerEvent('esx_skin:save', skin)
|
||||
end)
|
||||
end, data2.current.value)
|
||||
end)
|
||||
end, function(data2, menu2)
|
||||
menu2.close()
|
||||
end)
|
||||
end)
|
||||
elseif data.current.value == 'remove_cloth' then
|
||||
menu.close()
|
||||
TriggerServerCallback('qb-houses:server:getPlayerDressing', function(dressing)
|
||||
elements = {}
|
||||
|
||||
for i = 1, #dressing, 1 do
|
||||
table.insert(elements, {
|
||||
label = dressing[i],
|
||||
value = i
|
||||
})
|
||||
end
|
||||
|
||||
ESX.UI.Menu.Open('default', GetCurrentResourceName(), 'remove_cloth', {
|
||||
title = Lang('HOUSING_MENU_DELETE_CLOTHES'),
|
||||
align = 'right',
|
||||
elements = elements
|
||||
}, function(data2, menu2)
|
||||
menu2.close()
|
||||
TriggerServerEvent('qb-houses:server:removeOutfit', data2.current.value)
|
||||
Notification(Lang('HOUSING_NOTIFICATION_OUTFIT_DELETE'), 'inform')
|
||||
end, function(data2, menu2)
|
||||
menu2.close()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end, function(data, menu)
|
||||
menu.close()
|
||||
end)
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'fivem-appearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
exports['fivem-appearance']:openWardrobe()
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'illenium-appearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('illenium-appearance:client:openOutfitMenu')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'mAppearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('codem-appearance:OpenWardrobe')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'p_appearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
exports['p_appearance']:openOutfits()
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'qb-clothing' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('qb-clothing:client:openOutfitMenu')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'qs-appearance' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('clothing:openOutfitMenu')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'raid_clothes' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('raid_clothes:openmenu')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'rcore_clothes' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('rcore_clothes:openOutfits')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'rcore_clothing' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('rcore_clothing:openChangingRoom')
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'sleek-clothestore' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
exports['sleek-clothestore']:OpenWardrobe()
|
||||
end
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
if Config.Wardrobe ~= 'tgiann-clothing' then
|
||||
return
|
||||
end
|
||||
|
||||
function openWardrobe()
|
||||
TriggerEvent('tgiann-clothing:openOutfitMenu')
|
||||
end
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
--[[
|
||||
Here you have the weather tyme configuration, you can modify it or even
|
||||
create your own! In case your inventory is not here, you can ask the
|
||||
creator to create a file following this example and add it!
|
||||
]]
|
||||
|
||||
if Config.Weather ~= 'cd_easytime' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('advancedgarages:GetWeatherSync')
|
||||
AddEventHandler('advancedgarages:GetWeatherSync', function(bool, time)
|
||||
if bool then
|
||||
Wait(150)
|
||||
TriggerEvent('cd_easytime:PauseSync', true)
|
||||
NetworkOverrideClockTime(time, 0, 0)
|
||||
ClearOverrideWeather()
|
||||
ClearWeatherTypePersist()
|
||||
SetWeatherTypePersist('CLEAR')
|
||||
SetWeatherTypeNow('CLEAR')
|
||||
SetWeatherTypeNowPersist('CLEAR')
|
||||
else
|
||||
Wait(150)
|
||||
TriggerEvent('cd_easytime:PauseSync', false)
|
||||
Debug('Time was resynchronized to the original')
|
||||
end
|
||||
end)
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
--[[
|
||||
Here you have the weather tyme configuration, you can modify it or even
|
||||
create your own! In case your inventory is not here, you can ask the
|
||||
creator to create a file following this example and add it!
|
||||
]]
|
||||
|
||||
if Config.Weather ~= 'qb-weathersync' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('advancedgarages:GetWeatherSync')
|
||||
AddEventHandler('advancedgarages:GetWeatherSync', function(bool, time)
|
||||
if bool then
|
||||
Wait(150)
|
||||
TriggerEvent('qb-weathersync:client:DisableSync')
|
||||
NetworkOverrideClockTime(time, 0, 0)
|
||||
ClearOverrideWeather()
|
||||
ClearWeatherTypePersist()
|
||||
SetWeatherTypePersist('CLEAR')
|
||||
SetWeatherTypeNow('CLEAR')
|
||||
SetWeatherTypeNowPersist('CLEAR')
|
||||
else
|
||||
Wait(150)
|
||||
TriggerEvent('qb-weathersync:client:EnableSync')
|
||||
Debug('Time was resynchronized to the original')
|
||||
end
|
||||
end)
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
--[[
|
||||
Here you have the weather tyme configuration, you can modify it or even
|
||||
create your own! In case your inventory is not here, you can ask the
|
||||
creator to create a file following this example and add it!
|
||||
]]
|
||||
|
||||
if Config.Weather ~= 'vSync' then
|
||||
return
|
||||
end
|
||||
|
||||
RegisterNetEvent('advancedgarages:GetWeatherSync')
|
||||
AddEventHandler('advancedgarages:GetWeatherSync', function(bool, time)
|
||||
if bool then
|
||||
Wait(150)
|
||||
TriggerEvent('vSync:updateWeather', 'EXTRASUNNY', false)
|
||||
NetworkOverrideClockTime(time, 0, 0)
|
||||
ClearOverrideWeather()
|
||||
ClearWeatherTypePersist()
|
||||
SetWeatherTypePersist('CLEAR')
|
||||
SetWeatherTypeNow('CLEAR')
|
||||
SetWeatherTypeNowPersist('CLEAR')
|
||||
else
|
||||
Wait(150)
|
||||
TriggerEvent('vSync:toggle', true)
|
||||
TriggerServerEvent('vSync:requestSync')
|
||||
Debug('Time was resynchronized to the original')
|
||||
end
|
||||
end)
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user