644 lines
22 KiB
Lua
644 lines
22 KiB
Lua
local config = require 'config.client'
|
|
local sharedConfig = require 'config.shared'
|
|
|
|
VehicleStatus = {}
|
|
|
|
-- zone check
|
|
local plateZones = {}
|
|
local dutyTargetBoxId = 'dutyTarget'
|
|
local stashTargetBoxId = 'stashTarget'
|
|
|
|
-- Exports
|
|
|
|
---@param plate string
|
|
---@return table?
|
|
local function getVehicleStatusList(plate)
|
|
return VehicleStatus[plate]
|
|
end
|
|
|
|
---@param plate string
|
|
---@param part string
|
|
---@return number?
|
|
local function getVehicleStatus(plate, part)
|
|
if VehicleStatus[plate] then
|
|
return VehicleStatus[plate][part]
|
|
end
|
|
end
|
|
|
|
local function setVehicleStatus(plate, part, level)
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, part, level)
|
|
end
|
|
|
|
exports('GetVehicleStatusList', getVehicleStatusList)
|
|
exports('GetVehicleStatus', getVehicleStatus)
|
|
exports('SetVehicleStatus', setVehicleStatus)
|
|
|
|
-- Functions
|
|
|
|
---@param id string
|
|
local function deleteTarget(id)
|
|
if config.useTarget then
|
|
exports.ox_target:removeZone(id)
|
|
else
|
|
if config.targets[id]?.zone then
|
|
config.targets[id].zone:remove()
|
|
end
|
|
end
|
|
|
|
config.targets[id] = nil
|
|
end
|
|
|
|
local function registerDutyTarget()
|
|
local coords = sharedConfig.locations.duty
|
|
local boxData = config.targets[dutyTargetBoxId] or {}
|
|
|
|
if boxData?.created then
|
|
return
|
|
end
|
|
|
|
if QBX.PlayerData.job.type ~= 'mechanic' then
|
|
return
|
|
end
|
|
|
|
local label = QBX.PlayerData.job.onduty and locale('labels.sign_off') or locale('labels.sign_in')
|
|
|
|
if config.useTarget then
|
|
dutyTargetBoxId = exports.ox_target:addBoxZone({
|
|
coords = coords,
|
|
size = vec3(2.5, 1.5, 1),
|
|
rotation = 338.16,
|
|
debug = config.debugPoly,
|
|
options = {{
|
|
label = label,
|
|
name = dutyTargetBoxId,
|
|
icon = 'fa fa-clipboard',
|
|
distance = 2.0,
|
|
serverEvent = "QBCore:ToggleDuty",
|
|
canInteract = function()
|
|
return QBX.PlayerData.job.type == 'mechanic'
|
|
end
|
|
}},
|
|
})
|
|
|
|
config.targets[dutyTargetBoxId] = {created = true}
|
|
else
|
|
local zone = lib.zones.box({
|
|
coords = coords,
|
|
size = vec3(1.5, 2, 2),
|
|
rotation = 338.16,
|
|
debug = config.debugPoly,
|
|
inside = function()
|
|
if QBX.PlayerData.job.onduty then
|
|
if IsControlJustPressed(0, 38) then
|
|
TriggerServerEvent("QBCore:ToggleDuty")
|
|
Wait(500)
|
|
end
|
|
end
|
|
end,
|
|
onEnter = function()
|
|
if QBX.PlayerData.job.onduty then
|
|
lib.showTextUI("[E] " .. label, {position = 'left-center'})
|
|
end
|
|
end,
|
|
onExit = function()
|
|
lib.hideTextUI()
|
|
end,
|
|
})
|
|
|
|
config.targets[dutyTargetBoxId] = {created = true, zone = zone}
|
|
end
|
|
end
|
|
|
|
local function registerStashTarget()
|
|
local coords = sharedConfig.locations.stash
|
|
local boxData = config.targets[stashTargetBoxId] or {}
|
|
|
|
if boxData?.created then
|
|
return
|
|
end
|
|
|
|
if QBX.PlayerData.job.type ~= 'mechanic' then
|
|
return
|
|
end
|
|
|
|
if config.useTarget then
|
|
stashTargetBoxId = exports.ox_target:addBoxZone({
|
|
coords = coords,
|
|
size = vec3(1.5, 1.0, 2),
|
|
rotation = 248.41,
|
|
debug = config.debugPoly,
|
|
options = {{
|
|
label = locale('labels.o_stash'),
|
|
name = stashTargetBoxId,
|
|
icon = 'fa fa-archive',
|
|
distance = 2.0,
|
|
event = "qb-mechanicjob:client:target:OpenStash",
|
|
canInteract = function()
|
|
return QBX.PlayerData.job.onduty and QBX.PlayerData.job.type == 'mechanic'
|
|
end
|
|
}},
|
|
})
|
|
|
|
config.targets[stashTargetBoxId] = {created = true}
|
|
else
|
|
local zone = lib.zones.box({
|
|
coords = coords,
|
|
size = vec3(1.5, 1.5, 2),
|
|
rotation = 248.41,
|
|
debug = config.debugPoly,
|
|
inside = function()
|
|
if QBX.PlayerData.job.onduty and QBX.PlayerData.job.type == 'mechanic' then
|
|
if IsControlJustPressed(0, 38) then
|
|
TriggerEvent("qb-mechanicjob:client:target:OpenStash")
|
|
Wait(500)
|
|
end
|
|
end
|
|
end,
|
|
onEnter = function()
|
|
if QBX.PlayerData.job.onduty and QBX.PlayerData.job.type == 'mechanic' then
|
|
lib.showTextUI(locale('labels.o_stash'), {position = 'left-center'})
|
|
end
|
|
end,
|
|
onExit = function()
|
|
lib.hideTextUI()
|
|
end,
|
|
})
|
|
|
|
config.targets[stashTargetBoxId] = {created = true, zone = zone}
|
|
end
|
|
end
|
|
|
|
local function registerGarageZone()
|
|
local coords = sharedConfig.locations.vehicle
|
|
local veh = cache.vehicle
|
|
|
|
lib.zones.box({
|
|
coords = coords.xyz,
|
|
size = vec3(15, 5, 6),
|
|
rotation = 340.0,
|
|
debug = config.debugPoly,
|
|
inside = function()
|
|
if QBX.PlayerData.job.onduty and QBX.PlayerData.job.type == 'mechanic' then
|
|
if IsControlJustPressed(0, 38) then
|
|
if veh then
|
|
DeleteVehicle(veh)
|
|
lib.hideTextUI()
|
|
else
|
|
lib.showContext('mechanicVehicles')
|
|
lib.hideTextUI()
|
|
end
|
|
Wait(500)
|
|
end
|
|
end
|
|
end,
|
|
onEnter = function()
|
|
if QBX.PlayerData.job.onduty and QBX.PlayerData.job.type == 'mechanic' then
|
|
local inVehicle = cache.vehicle
|
|
if inVehicle then
|
|
lib.showTextUI(locale('labels.h_vehicle'), {position = 'left-center'})
|
|
else
|
|
lib.showTextUI(locale('labels.g_vehicle'), {position = 'left-center'})
|
|
end
|
|
end
|
|
end,
|
|
onExit = function()
|
|
lib.hideTextUI()
|
|
end,
|
|
})
|
|
end
|
|
|
|
local closestPlate = nil
|
|
|
|
local function destroyVehiclePlateZone(id)
|
|
if not plateZones[id] then
|
|
return
|
|
end
|
|
|
|
plateZones[id]:remove()
|
|
plateZones[id] = nil
|
|
end
|
|
|
|
local function registerVehiclePlateZone(id, plate)
|
|
local coords = plate.coords
|
|
local boxData = plate.boxData
|
|
closestPlate = id
|
|
|
|
local plateZone = lib.zones.box({
|
|
coords = coords.xyz,
|
|
size = vec3(boxData.width, boxData.length, 4),
|
|
rotation = boxData.heading,
|
|
debug = boxData.debugPoly,
|
|
inside = function()
|
|
if QBX.PlayerData.job.onduty then
|
|
local veh = cache.vehicle
|
|
if plate.AttachedVehicle then
|
|
if IsControlJustPressed(0, 38) then
|
|
lib.hideTextUI()
|
|
lib.showContext('lift')
|
|
end
|
|
elseif IsControlJustPressed(0, 38) and veh then
|
|
DoScreenFadeOut(150)
|
|
Wait(150)
|
|
plate.AttachedVehicle = veh
|
|
SetEntityCoords(veh, coords.x, coords.y, coords.z, false, false, false, false)
|
|
SetEntityHeading(veh, coords.w)
|
|
FreezeEntityPosition(veh, true)
|
|
Wait(500)
|
|
DoScreenFadeIn(150)
|
|
TriggerServerEvent('qb-vehicletuning:server:SetAttachedVehicle', id, veh)
|
|
destroyVehiclePlateZone(plate)
|
|
registerVehiclePlateZone(id, plate)
|
|
end
|
|
end
|
|
end,
|
|
onEnter = function()
|
|
if not QBX.PlayerData.job.onduty then
|
|
return
|
|
end
|
|
|
|
if plate.AttachedVehicle then
|
|
lib.showTextUI(locale('labels.o_menu'), {position = 'left-center'})
|
|
elseif cache.vehicle then
|
|
lib.showTextUI(locale('labels.work_v'), {position = 'left-center'})
|
|
end
|
|
end,
|
|
onExit = function()
|
|
lib.hideTextUI()
|
|
end,
|
|
})
|
|
|
|
plateZones[id] = plateZone
|
|
end
|
|
|
|
local function setVehiclePlateZones()
|
|
if #sharedConfig.plates > 0 then
|
|
for i = 1, #sharedConfig.plates do
|
|
local plate = sharedConfig.plates[i]
|
|
registerVehiclePlateZone(i, plate)
|
|
end
|
|
else
|
|
print('No vehicle plates configured')
|
|
end
|
|
end
|
|
|
|
local function sendStatusMessage(statusList)
|
|
if not statusList then return end
|
|
local templateStart = '<div class="chat-message normal"><div class="chat-message-body"><strong>{0}:</strong><br><br> '
|
|
local templateEnd = '</div></div>'
|
|
local templateMiddle = '<strong>'.. config.partLabels.engine ..' (engine):</strong> {1} <br><strong>'.. config.partLabels.body ..' (body):</strong> {2} <br><strong>'.. config.partLabels.radiator ..' (radiator):</strong> {3} <br><strong>'.. config.partLabels.axle ..' (axle):</strong> {4}<br><strong>'.. config.partLabels.brakes ..' (brakes):</strong> {5}<br><strong>'.. config.partLabels.clutch ..' (clutch):</strong> {6}<br><strong>'.. config.partLabels.fuel ..' (fuel):</strong> {7}'
|
|
TriggerEvent('chat:addMessage', {
|
|
template = templateStart .. templateMiddle .. templateEnd,
|
|
args = {locale('labels.veh_status'),
|
|
qbx.math.round(statusList.engine) .. "/" .. sharedConfig.maxStatusValues.engine .. " ("..exports.ox_inventory:Items().advancedrepairkit.label..")",
|
|
qbx.math.round(statusList.body) .. "/" .. sharedConfig.maxStatusValues.body .. " ("..exports.ox_inventory:Items()[sharedConfig.repairCost.body].label..")",
|
|
qbx.math.round(statusList.radiator) .. "/" .. sharedConfig.maxStatusValues.radiator .. ".0 ("..exports.ox_inventory:Items()[sharedConfig.repairCost.radiator].label..")",
|
|
qbx.math.round(statusList.axle) .. "/" .. sharedConfig.maxStatusValues.axle .. ".0 ("..exports.ox_inventory:Items()[sharedConfig.repairCost.axle].label..")",
|
|
qbx.math.round(statusList.brakes) .. "/" .. sharedConfig.maxStatusValues.brakes .. ".0 ("..exports.ox_inventory:Items()[sharedConfig.repairCost.brakes].label..")",
|
|
qbx.math.round(statusList.clutch) .. "/" .. sharedConfig.maxStatusValues.clutch .. ".0 ("..exports.ox_inventory:Items()[sharedConfig.repairCost.clutch].label..")",
|
|
qbx.math.round(statusList.fuel) .. "/" .. sharedConfig.maxStatusValues.fuel .. ".0 ("..exports.ox_inventory:Items()[sharedConfig.repairCost.fuel].label..")"
|
|
}
|
|
})
|
|
end
|
|
|
|
local function detachVehicle()
|
|
DoScreenFadeOut(150)
|
|
Wait(150)
|
|
local plate = sharedConfig.plates[closestPlate]
|
|
FreezeEntityPosition(plate.AttachedVehicle, false)
|
|
SetEntityCoords(plate.AttachedVehicle, plate.coords.x, plate.coords.y, plate.coords.z, false, false, false, false)
|
|
SetEntityHeading(plate.AttachedVehicle, plate.coords.w)
|
|
TaskWarpPedIntoVehicle(cache.ped, plate.AttachedVehicle, -1)
|
|
Wait(500)
|
|
DoScreenFadeIn(250)
|
|
|
|
plate.AttachedVehicle = nil
|
|
TriggerServerEvent('qb-vehicletuning:server:SetAttachedVehicle', closestPlate, false)
|
|
|
|
destroyVehiclePlateZone(closestPlate)
|
|
registerVehiclePlateZone(closestPlate, plate)
|
|
end
|
|
|
|
local function checkStatus()
|
|
local plate = qbx.getVehiclePlate(sharedConfig.plates[closestPlate].AttachedVehicle)
|
|
sendStatusMessage(VehicleStatus[plate])
|
|
end
|
|
|
|
local function repairPart(part)
|
|
local hasEnough = lib.callback.await('qbx_mechanicjob:server:checkForItems', false, part)
|
|
if not hasEnough then
|
|
local itemName = sharedConfig.repairCostAmount[part].item
|
|
local amountRequired = sharedConfig.repairCostAmount[part].costs
|
|
return exports.qbx_core:Notify(locale('notifications.not_enough', exports.ox_inventory:Items()[itemName].label, amountRequired), 'error')
|
|
end
|
|
|
|
exports.scully_emotemenu:playEmoteByCommand('mechanic')
|
|
if lib.progressBar({
|
|
duration = math.random(5000, 10000),
|
|
label = locale('labels.progress_bar', string.lower(config.partLabels[part])),
|
|
canCancel = true,
|
|
disable = {
|
|
move = true,
|
|
car = true,
|
|
combat = true,
|
|
mouse = false,
|
|
}
|
|
}) then
|
|
exports.scully_emotemenu:cancelEmote()
|
|
local veh = sharedConfig.plates[closestPlate].AttachedVehicle
|
|
local plate = qbx.getVehiclePlate(veh)
|
|
if part == "engine" then
|
|
SetVehicleEngineHealth(veh, sharedConfig.maxStatusValues[part])
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, "engine", sharedConfig.maxStatusValues[part])
|
|
elseif part == "body" then
|
|
local enhealth = GetVehicleEngineHealth(veh)
|
|
local realFuel = GetVehicleFuelLevel(veh)
|
|
SetVehicleBodyHealth(veh, sharedConfig.maxStatusValues[part])
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, "body", sharedConfig.maxStatusValues[part])
|
|
SetVehicleFixed(veh)
|
|
SetVehicleEngineHealth(veh, enhealth)
|
|
if GetVehicleFuelLevel(veh) ~= realFuel then
|
|
SetVehicleFuelLevel(veh, realFuel)
|
|
end
|
|
else
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, part, sharedConfig.maxStatusValues[part])
|
|
end
|
|
exports.qbx_core:Notify(locale('notifications.partrep', config.partLabels[part]))
|
|
Wait(250)
|
|
OpenVehicleStatusMenu()
|
|
else
|
|
exports.scully_emotemenu:cancelEmote()
|
|
exports.qbx_core:Notify(locale('notifications.rep_canceled'), "error")
|
|
end
|
|
end
|
|
|
|
local function openPartMenu(data)
|
|
local partName = data.name
|
|
local part = data.parts
|
|
local options = {
|
|
{
|
|
title = partName,
|
|
description = locale('parts_menu.repair_op', exports.ox_inventory:Items()[sharedConfig.repairCostAmount[part].item].label, sharedConfig.repairCostAmount[part].costs),
|
|
onSelect = function()
|
|
repairPart(part)
|
|
end,
|
|
},
|
|
}
|
|
|
|
lib.registerContext({
|
|
id = 'part',
|
|
title = locale('parts_menu.menu_header'),
|
|
options = options,
|
|
menu = 'vehicleStatus',
|
|
})
|
|
|
|
lib.showContext('part')
|
|
end
|
|
|
|
function OpenVehicleStatusMenu()
|
|
local plate = qbx.getVehiclePlate(sharedConfig.plates[closestPlate].AttachedVehicle)
|
|
if not VehicleStatus[plate] then return end
|
|
|
|
local options = {}
|
|
|
|
for partName, label in pairs(config.partLabels) do
|
|
if math.ceil(VehicleStatus[plate][partName]) ~= sharedConfig.maxStatusValues[partName] then
|
|
local percentage = math.ceil(VehicleStatus[plate][partName])
|
|
if percentage > 100 then
|
|
percentage = math.ceil(VehicleStatus[plate][partName]) / 10
|
|
end
|
|
options[#options+1] = {
|
|
title = label,
|
|
description = locale('parts_menu.status', percentage),
|
|
onSelect = function()
|
|
openPartMenu({
|
|
name = label,
|
|
parts = partName
|
|
})
|
|
end,
|
|
arrow = true,
|
|
}
|
|
else
|
|
local percentage = math.ceil(sharedConfig.maxStatusValues[partName])
|
|
if percentage > 100 then
|
|
percentage = math.ceil(sharedConfig.maxStatusValues[partName]) / 10
|
|
end
|
|
options[#options+1] = {
|
|
title = label,
|
|
description = locale('parts_menu.status', percentage),
|
|
onSelect = OpenVehicleStatusMenu,
|
|
arrow = true,
|
|
}
|
|
end
|
|
end
|
|
|
|
lib.registerContext({
|
|
id = 'vehicleStatus',
|
|
title = locale('labels.status'),
|
|
options = options,
|
|
})
|
|
|
|
lib.showContext('vehicleStatus')
|
|
end
|
|
|
|
local function resetClosestVehiclePlate()
|
|
destroyVehiclePlateZone(closestPlate)
|
|
registerVehiclePlateZone(closestPlate, sharedConfig.plates[closestPlate])
|
|
end
|
|
|
|
local function spawnListVehicle(model)
|
|
local netId = lib.callback.await('qbx_mechanicjob:server:spawnVehicle', false, model, sharedConfig.locations.vehicle, true)
|
|
local timeout = 100
|
|
while not NetworkDoesEntityExistWithNetworkId(netId) and timeout > 0 do
|
|
Wait(10)
|
|
timeout -= 1
|
|
end
|
|
local veh = NetworkGetEntityFromNetworkId(netId)
|
|
SetVehicleNumberPlateText(veh, "MECH"..tostring(math.random(1000, 9999)))
|
|
SetVehicleFuelLevel(veh, 100.0)
|
|
TaskWarpPedIntoVehicle(cache.ped, veh, -1)
|
|
TriggerEvent("vehiclekeys:client:SetOwner", qbx.getVehiclePlate(veh))
|
|
SetVehicleEngineOn(veh, true, true, false)
|
|
end
|
|
|
|
local function createBlip()
|
|
local blip = AddBlipForCoord(sharedConfig.locations.exit.x, sharedConfig.locations.exit.y, sharedConfig.locations.exit.z)
|
|
SetBlipSprite(blip, 446)
|
|
SetBlipDisplay(blip, 4)
|
|
SetBlipScale(blip, 0.7)
|
|
SetBlipColour(blip, 0)
|
|
SetBlipAsShortRange(blip, true)
|
|
BeginTextCommandSetBlipName("STRING")
|
|
AddTextComponentString(locale('labels.job_blip'))
|
|
EndTextCommandSetBlipName(blip)
|
|
end
|
|
|
|
-- Events
|
|
|
|
AddEventHandler('onResourceStart', function(resource)
|
|
if resource ~= GetCurrentResourceName() then return end
|
|
|
|
createBlip()
|
|
registerGarageZone()
|
|
registerDutyTarget()
|
|
registerStashTarget()
|
|
setVehiclePlateZones()
|
|
if QBX.PlayerData.job.onduty and QBX.PlayerData.type == 'mechanic' then
|
|
TriggerServerEvent("QBCore:ToggleDuty")
|
|
end
|
|
|
|
lib.callback('qb-vehicletuning:server:GetAttachedVehicle', false, function(plates)
|
|
for k, v in pairs(plates) do
|
|
sharedConfig.plates[k].AttachedVehicle = v.AttachedVehicle
|
|
end
|
|
end)
|
|
|
|
lib.callback('qb-vehicletuning:server:GetDrivingDistances', false, function(retval)
|
|
DrivingDistance = retval
|
|
end)
|
|
end)
|
|
|
|
AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
|
|
createBlip()
|
|
registerGarageZone()
|
|
registerDutyTarget()
|
|
registerStashTarget()
|
|
setVehiclePlateZones()
|
|
if QBX.PlayerData.job.onduty and QBX.PlayerData.type == 'mechanic' then
|
|
TriggerServerEvent("QBCore:ToggleDuty")
|
|
end
|
|
|
|
lib.callback('qb-vehicletuning:server:GetAttachedVehicle', false, function(plates)
|
|
for k, v in pairs(plates) do
|
|
sharedConfig.plates[k].AttachedVehicle = v.AttachedVehicle
|
|
end
|
|
end)
|
|
|
|
lib.callback('qb-vehicletuning:server:GetDrivingDistances', false, function(retval)
|
|
DrivingDistance = retval
|
|
end)
|
|
end)
|
|
|
|
RegisterNetEvent('QBCore:Client:OnJobUpdate', function()
|
|
deleteTarget(dutyTargetBoxId)
|
|
deleteTarget(stashTargetBoxId)
|
|
|
|
if QBX.PlayerData.type ~= 'mechanic' then return end
|
|
|
|
registerDutyTarget()
|
|
|
|
if not QBX.PlayerData.job.onduty then return end
|
|
registerStashTarget()
|
|
end)
|
|
|
|
RegisterNetEvent('QBCore:Client:SetDuty', function()
|
|
deleteTarget(dutyTargetBoxId)
|
|
deleteTarget(stashTargetBoxId)
|
|
|
|
if QBX.PlayerData.type == 'mechanic' then
|
|
registerDutyTarget()
|
|
|
|
if not QBX.PlayerData.job.onduty then return end
|
|
registerStashTarget()
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent('qb-vehicletuning:client:SetAttachedVehicle', function(veh, key)
|
|
sharedConfig.plates[key].AttachedVehicle = veh
|
|
end)
|
|
|
|
RegisterNetEvent('vehiclemod:client:setVehicleStatus', function(plate, status)
|
|
VehicleStatus[plate] = status
|
|
end)
|
|
|
|
RegisterNetEvent('vehiclemod:client:fixEverything', function()
|
|
local veh = cache.vehicle
|
|
if not veh then
|
|
exports.qbx_core:Notify(locale('notifications.not_vehicle'), "error")
|
|
return
|
|
end
|
|
|
|
if IsThisModelABicycle(GetEntityModel(veh)) or cache.seat ~= -1 then
|
|
exports.qbx_core:Notify(locale('notifications.wrong_seat'), "error")
|
|
end
|
|
|
|
local plate = qbx.getVehiclePlate(veh)
|
|
TriggerServerEvent("vehiclemod:server:fixEverything", plate)
|
|
end)
|
|
|
|
RegisterNetEvent('vehiclemod:client:setPartLevel', function(part, level)
|
|
local veh = cache.vehicle
|
|
if not veh then
|
|
exports.qbx_core:Notify(locale('notifications.not_vehicle'), "error")
|
|
return
|
|
end
|
|
|
|
if IsThisModelABicycle(GetEntityModel(veh)) or cache.seat ~= -1 then
|
|
exports.qbx_core:Notify(locale('notifications.wrong_seat'), "error")
|
|
return
|
|
end
|
|
|
|
local plate = qbx.getVehiclePlate(veh)
|
|
if part == "engine" then
|
|
SetVehicleEngineHealth(veh, level)
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, "engine", GetVehicleEngineHealth(veh))
|
|
elseif part == "body" then
|
|
SetVehicleBodyHealth(veh, level)
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, "body", GetVehicleBodyHealth(veh))
|
|
else
|
|
TriggerServerEvent("vehiclemod:server:updatePart", plate, part, level)
|
|
end
|
|
end)
|
|
|
|
AddEventHandler('qb-mechanicjob:client:target:OpenStash', function()
|
|
exports.ox_inventory:openInventory('stash', {id = 'mechanicstash'})
|
|
end)
|
|
|
|
-- Static menus
|
|
|
|
local function registerLiftMenu()
|
|
lib.registerContext({
|
|
id = 'lift',
|
|
title = locale('lift_menu.header_menu'),
|
|
onExit = resetClosestVehiclePlate,
|
|
options = {
|
|
{
|
|
title = locale('lift_menu.header_vehdc'),
|
|
description = locale('lift_menu.desc_vehdc'),
|
|
onSelect = detachVehicle,
|
|
},
|
|
{
|
|
title = locale('lift_menu.header_stats'),
|
|
description = locale('lift_menu.desc_stats'),
|
|
onSelect = checkStatus,
|
|
},
|
|
{
|
|
title = locale('lift_menu.header_parts'),
|
|
description = locale('lift_menu.desc_parts'),
|
|
arrow = true,
|
|
onSelect = OpenVehicleStatusMenu,
|
|
}
|
|
}
|
|
})
|
|
end
|
|
|
|
local function registerVehicleListMenu()
|
|
local options = {}
|
|
for k, v in pairs(config.vehicles) do
|
|
options[#options + 1] = {
|
|
title = v,
|
|
description = locale('labels.vehicle_title', v),
|
|
onSelect = function()
|
|
spawnListVehicle(k)
|
|
end,
|
|
}
|
|
end
|
|
|
|
lib.registerContext({
|
|
id = 'mechanicVehicles',
|
|
title = locale('labels.vehicle_list'),
|
|
options = options,
|
|
})
|
|
end
|
|
|
|
registerLiftMenu()
|
|
registerVehicleListMenu() |