structura foldere

mutat kq- folders in un singur folder [kq]
This commit is contained in:
2026-03-30 01:55:03 +03:00
parent af1286d583
commit c291b81f26
2319 changed files with 0 additions and 14 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'codem-appearance' then
return
end
function openWardrobe()
TriggerEvent('codem-apperance:OpenWardrobe')
end

View File

@@ -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

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'fivem-appearance' then
return
end
function openWardrobe()
exports['fivem-appearance']:openWardrobe()
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'illenium-appearance' then
return
end
function openWardrobe()
TriggerEvent('illenium-appearance:client:openOutfitMenu')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'mAppearance' then
return
end
function openWardrobe()
TriggerEvent('codem-appearance:OpenWardrobe')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'p_appearance' then
return
end
function openWardrobe()
exports['p_appearance']:openOutfits()
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'qb-clothing' then
return
end
function openWardrobe()
TriggerEvent('qb-clothing:client:openOutfitMenu')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'qs-appearance' then
return
end
function openWardrobe()
TriggerEvent('clothing:openOutfitMenu')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'raid_clothes' then
return
end
function openWardrobe()
TriggerEvent('raid_clothes:openmenu')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'rcore_clothes' then
return
end
function openWardrobe()
TriggerEvent('rcore_clothes:openOutfits')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'rcore_clothing' then
return
end
function openWardrobe()
TriggerEvent('rcore_clothing:openChangingRoom')
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'sleek-clothestore' then
return
end
function openWardrobe()
exports['sleek-clothestore']:OpenWardrobe()
end

View File

@@ -0,0 +1,7 @@
if Config.Wardrobe ~= 'tgiann-clothing' then
return
end
function openWardrobe()
TriggerEvent('tgiann-clothing:openOutfitMenu')
end

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)