924 lines
		
	
	
		
			No EOL
		
	
	
		
			28 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			924 lines
		
	
	
		
			No EOL
		
	
	
		
			28 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
---Set statebags (via server) from props. For apply orders, persistence integrations + backwards compat
 | 
						|
---@param vehicle any
 | 
						|
---@param props any
 | 
						|
function setStatebagsFromProps(vehicle, props)
 | 
						|
  if not vehicle or vehicle == 0 or not props or type(props) ~= "table" then
 | 
						|
    debugPrint("Could not run setStatebagsFromProps", "warning", vehicle, json.encode(props))
 | 
						|
    return false
 | 
						|
  end
 | 
						|
 | 
						|
  -- Setting a statebag for perf mods is required because we have to set them again
 | 
						|
  -- after making handling changes, otherwise vehicles become like 15-20% slower.
 | 
						|
  -- I don't know. GTA things.
 | 
						|
  if props.modEngine or props.modBrakes or props.modTransmission or props.modTurbo then
 | 
						|
    local perfMods = props.performanceMods or {}
 | 
						|
 | 
						|
    if props.modEngine ~= nil then perfMods.modEngine = props.modEngine end
 | 
						|
    if props.modBrakes ~= nil then perfMods.modBrakes = props.modBrakes end
 | 
						|
    if props.modTransmission ~= nil then perfMods.modTransmission = props.modTransmission end
 | 
						|
    if props.modTurbo ~= nil then perfMods.modTurbo = props.modTurbo end
 | 
						|
 | 
						|
    setVehicleStatebag(vehicle, "performanceMods", perfMods)
 | 
						|
  end
 | 
						|
  
 | 
						|
  -- Custom menu properties
 | 
						|
  if props.primarySecondarySync then
 | 
						|
    setVehicleStatebag(vehicle, "primarySecondarySync", props.primarySecondarySync)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.disablePearl then
 | 
						|
    setVehicleStatebag(vehicle, "disablePearl", props.disablePearl)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.enableStance ~= nil then
 | 
						|
    setVehicleStatebag(vehicle, "enableStance", props.enableStance)
 | 
						|
  end 
 | 
						|
  
 | 
						|
  if props.wheelsAdjIndv then
 | 
						|
    setVehicleStatebag(vehicle, "wheelsAdjIndv", props.wheelsAdjIndv)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.stance then
 | 
						|
    setVehicleStatebag(vehicle, "stance", props.stance)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.lcInstalled then
 | 
						|
    setVehicleStatebag(vehicle, "lightingControllerInstalled", props.lcInstalled)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.lcXenons then
 | 
						|
    setVehicleStatebag(vehicle, "xenons", props.lcXenons)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.lcUnderglowDirections then
 | 
						|
    setVehicleStatebag(vehicle, "underglowDirections", props.lcUnderglowDirections)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.lcUnderglow then
 | 
						|
    setVehicleStatebag(vehicle, "underglow", props.lcUnderglow)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tuningConfig then
 | 
						|
    setVehicleStatebag(vehicle, "tuningConfig", props.tuningConfig)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.servicingData then
 | 
						|
    setVehicleStatebag(vehicle, "servicingData", props.servicingData)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.nitrousInstalledBottles then
 | 
						|
    setVehicleStatebag(vehicle, "nitrousInstalledBottles", props.nitrousInstalledBottles)
 | 
						|
  end
 | 
						|
  
 | 
						|
  if props.nitrousFilledBottles then
 | 
						|
    setVehicleStatebag(vehicle, "nitrousFilledBottles", props.nitrousFilledBottles)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.nitrousCapacity then
 | 
						|
    setVehicleStatebag(vehicle, "nitrousCapacity", props.nitrousCapacity)
 | 
						|
  end
 | 
						|
 | 
						|
  setVehicleStatebag(vehicle, "_sbFromPropsSet", true, true)
 | 
						|
end
 | 
						|
 | 
						|
---@param vehicle integer
 | 
						|
---@param withStatebags? boolean
 | 
						|
function getVehicleProperties(vehicle, withStatebags)
 | 
						|
  if not DoesEntityExist(vehicle) then return false end
 | 
						|
 | 
						|
  ---@type number | number[], number | number[]
 | 
						|
  local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
 | 
						|
  local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
 | 
						|
  local paintType1 = GetVehicleModColor_1(vehicle)
 | 
						|
  local paintType2 = GetVehicleModColor_2(vehicle)
 | 
						|
 | 
						|
  if GetIsVehiclePrimaryColourCustom(vehicle) then
 | 
						|
    colorPrimary = { GetVehicleCustomPrimaryColour(vehicle) }
 | 
						|
  end
 | 
						|
 | 
						|
  if GetIsVehicleSecondaryColourCustom(vehicle) then
 | 
						|
    colorSecondary = { GetVehicleCustomSecondaryColour(vehicle) }
 | 
						|
  end
 | 
						|
 | 
						|
  local extras = {}
 | 
						|
  for extraId = 1, 15 do
 | 
						|
    if DoesExtraExist(vehicle, extraId) then
 | 
						|
      extras[tostring(extraId)] = IsVehicleExtraTurnedOn(vehicle, extraId) == 1
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  local modLiveryCount = GetVehicleLiveryCount(vehicle)
 | 
						|
  local modLivery = GetVehicleLivery(vehicle)
 | 
						|
 | 
						|
  if modLiveryCount == -1 or modLivery == -1 then
 | 
						|
    modLivery = GetVehicleMod(vehicle, 48)
 | 
						|
  end
 | 
						|
 | 
						|
  local tireHealth = {}
 | 
						|
  for i = 0, 3 do
 | 
						|
    tireHealth[i] = GetVehicleWheelHealth(vehicle, i)
 | 
						|
  end
 | 
						|
 | 
						|
  local tireBurstState = {}
 | 
						|
  for i = 0, 5 do
 | 
						|
    tireBurstState[i] = IsVehicleTyreBurst(vehicle, i, false)
 | 
						|
  end
 | 
						|
 | 
						|
  local tireBurstCompletely = {}
 | 
						|
  for i = 0, 5 do
 | 
						|
    tireBurstCompletely[i] = IsVehicleTyreBurst(vehicle, i, true)
 | 
						|
  end
 | 
						|
 | 
						|
  local windowStatus = {}
 | 
						|
  for i = 0, 7 do
 | 
						|
    windowStatus[i] = IsVehicleWindowIntact(vehicle, i) == 1
 | 
						|
  end
 | 
						|
 | 
						|
  local doorStatus = {}
 | 
						|
  for i = 0, 5 do
 | 
						|
    doorStatus[i] = IsVehicleDoorDamaged(vehicle, i) == 1
 | 
						|
  end
 | 
						|
 | 
						|
  local neons = {}
 | 
						|
  for i = 0, 3 do
 | 
						|
    neons[i + 1] = IsVehicleNeonLightEnabled(vehicle, i)
 | 
						|
  end
 | 
						|
 | 
						|
  local xenonCustomColor = {}
 | 
						|
  local xenonCustomColorEnabled, x_red, x_green, x_blue = GetVehicleXenonLightsCustomColor(vehicle)
 | 
						|
  if xenonCustomColorEnabled then
 | 
						|
    xenonCustomColor = {x_red, x_green, x_blue}
 | 
						|
  end
 | 
						|
 | 
						|
  -- ESX COMPATIBILITY
 | 
						|
  local hasCustomPrimaryColor = GetIsVehiclePrimaryColourCustom(vehicle)
 | 
						|
  local customPrimaryColor = nil
 | 
						|
  if hasCustomPrimaryColor then
 | 
						|
      customPrimaryColor = { GetVehicleCustomPrimaryColour(vehicle) }
 | 
						|
  end
 | 
						|
 | 
						|
  local hasCustomSecondaryColor = GetIsVehicleSecondaryColourCustom(vehicle)
 | 
						|
  local customSecondaryColor = nil
 | 
						|
  if hasCustomSecondaryColor then
 | 
						|
    customSecondaryColor = { GetVehicleCustomSecondaryColour(vehicle) }
 | 
						|
  end
 | 
						|
 | 
						|
  local hasCustomXenonColor, customXenonColorR, customXenonColorG, customXenonColorB = GetVehicleXenonLightsCustomColor(vehicle)
 | 
						|
  local customXenonColor = nil
 | 
						|
  if hasCustomXenonColor then
 | 
						|
    customXenonColor = { customXenonColorR, customXenonColorG, customXenonColorB }
 | 
						|
  end
 | 
						|
 | 
						|
  local doorsBroken, windowsBroken, tyreBurst = {}, {}, {}
 | 
						|
  local numWheels = tostring(GetVehicleNumberOfWheels(vehicle))
 | 
						|
 | 
						|
  local tyresIndex = {
 | 
						|
    ["2"] = { 0, 4 },
 | 
						|
    ["3"] = { 0, 1, 4, 5 },
 | 
						|
    ["4"] = { 0, 1, 4, 5 },
 | 
						|
    ["6"] = { 0, 1, 2, 3, 4, 5 },
 | 
						|
  }
 | 
						|
 | 
						|
  if tyresIndex[numWheels] then
 | 
						|
    for _, idx in pairs(tyresIndex[numWheels]) do
 | 
						|
      tyreBurst[tostring(idx)] = IsVehicleTyreBurst(vehicle, idx, false)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  for windowId = 0, 7 do -- 13
 | 
						|
    windowsBroken[tostring(windowId)] = not IsVehicleWindowIntact(vehicle, windowId)
 | 
						|
  end
 | 
						|
 | 
						|
  local numDoors = GetNumberOfVehicleDoors(vehicle)
 | 
						|
  if numDoors and numDoors > 0 then
 | 
						|
    for doorsId = 0, numDoors do
 | 
						|
      doorsBroken[tostring(doorsId)] = IsVehicleDoorDamaged(vehicle, doorsId)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  -- END ESX COMPATIBILITY
 | 
						|
  
 | 
						|
  local props = {
 | 
						|
    model = GetEntityModel(vehicle),
 | 
						|
    plate = GetVehicleNumberPlateText(vehicle),
 | 
						|
    plateIndex = GetVehicleNumberPlateTextIndex(vehicle),
 | 
						|
    bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) + 0.5) + 0.0,
 | 
						|
    engineHealth = math.floor(GetVehicleEngineHealth(vehicle) + 0.5) + 0.0,
 | 
						|
    tankHealth = math.floor(GetVehiclePetrolTankHealth(vehicle) + 0.5) + 0.0,
 | 
						|
    fuelLevel = math.floor(GetVehicleFuelLevel(vehicle) + 0.5) + 0.0,
 | 
						|
    oilLevel = math.floor(GetVehicleOilLevel(vehicle) + 0.5) + 0.0,
 | 
						|
    dirtLevel = math.floor(GetVehicleDirtLevel(vehicle) + 0.5) + 0.0,
 | 
						|
    paintType1 = paintType1,
 | 
						|
    paintType2 = paintType2,
 | 
						|
    color1 = colorPrimary,
 | 
						|
    color2 = colorSecondary,
 | 
						|
    pearlescentColor = pearlescentColor,
 | 
						|
    interiorColor = GetVehicleInteriorColor(vehicle),
 | 
						|
    dashboardColor = GetVehicleDashboardColour(vehicle),
 | 
						|
    wheelColor = wheelColor,
 | 
						|
    wheelWidth = GetVehicleWheelWidth(vehicle),
 | 
						|
    wheelSize = GetVehicleWheelSize(vehicle),
 | 
						|
    wheels = GetVehicleWheelType(vehicle),
 | 
						|
    tireHealth = tireHealth,
 | 
						|
    tireBurstState = tireBurstState,
 | 
						|
    tireBurstCompletely = tireBurstCompletely,
 | 
						|
    windowTint = GetVehicleWindowTint(vehicle),
 | 
						|
    windowStatus = windowStatus,
 | 
						|
    doorStatus = doorStatus,
 | 
						|
    xenonColor = GetVehicleXenonLightsColor(vehicle),
 | 
						|
    neonEnabled = neons,
 | 
						|
    neonColor = { GetVehicleNeonLightsColour(vehicle) },
 | 
						|
    extras = extras,
 | 
						|
    tyreSmokeColor = { GetVehicleTyreSmokeColor(vehicle) },
 | 
						|
    modSpoilers = GetVehicleMod(vehicle, 0),
 | 
						|
    modFrontBumper = GetVehicleMod(vehicle, 1),
 | 
						|
    modRearBumper = GetVehicleMod(vehicle, 2),
 | 
						|
    modSideSkirt = GetVehicleMod(vehicle, 3),
 | 
						|
    modExhaust = GetVehicleMod(vehicle, 4),
 | 
						|
    modFrame = GetVehicleMod(vehicle, 5),
 | 
						|
    modGrille = GetVehicleMod(vehicle, 6),
 | 
						|
    modHood = GetVehicleMod(vehicle, 7),
 | 
						|
    modFender = GetVehicleMod(vehicle, 8),
 | 
						|
    modRightFender = GetVehicleMod(vehicle, 9),
 | 
						|
    modRoof = GetVehicleMod(vehicle, 10),
 | 
						|
    modEngine = GetVehicleMod(vehicle, 11),
 | 
						|
    modBrakes = GetVehicleMod(vehicle, 12),
 | 
						|
    modTransmission = GetVehicleMod(vehicle, 13),
 | 
						|
    modHorns = GetVehicleMod(vehicle, 14),
 | 
						|
    modSuspension = GetVehicleMod(vehicle, 15),
 | 
						|
    modArmor = GetVehicleMod(vehicle, 16),
 | 
						|
    modNitrous = GetVehicleMod(vehicle, 17),
 | 
						|
    modTurbo = IsToggleModOn(vehicle, 18),
 | 
						|
    modSubwoofer = GetVehicleMod(vehicle, 19),
 | 
						|
    modSmokeEnabled = IsToggleModOn(vehicle, 20),
 | 
						|
    modHydraulics = IsToggleModOn(vehicle, 21),
 | 
						|
    modXenon = IsToggleModOn(vehicle, 22),
 | 
						|
    modFrontWheels = GetVehicleMod(vehicle, 23),
 | 
						|
    modBackWheels = GetVehicleMod(vehicle, 24),
 | 
						|
    modCustomTiresF = GetVehicleModVariation(vehicle, 23),
 | 
						|
    modCustomTiresR = GetVehicleModVariation(vehicle, 24),
 | 
						|
    modPlateHolder = GetVehicleMod(vehicle, 25),
 | 
						|
    modVanityPlate = GetVehicleMod(vehicle, 26),
 | 
						|
    modTrimA = GetVehicleMod(vehicle, 27),
 | 
						|
    modOrnaments = GetVehicleMod(vehicle, 28),
 | 
						|
    modDashboard = GetVehicleMod(vehicle, 29),
 | 
						|
    modDial = GetVehicleMod(vehicle, 30),
 | 
						|
    modDoorSpeaker = GetVehicleMod(vehicle, 31),
 | 
						|
    modSeats = GetVehicleMod(vehicle, 32),
 | 
						|
    modSteeringWheel = GetVehicleMod(vehicle, 33),
 | 
						|
    modShifterLeavers = GetVehicleMod(vehicle, 34),
 | 
						|
    modAPlate = GetVehicleMod(vehicle, 35),
 | 
						|
    modSpeakers = GetVehicleMod(vehicle, 36),
 | 
						|
    modTrunk = GetVehicleMod(vehicle, 37),
 | 
						|
    modHydrolic = GetVehicleMod(vehicle, 38),
 | 
						|
    modEngineBlock = GetVehicleMod(vehicle, 39),
 | 
						|
    modAirFilter = GetVehicleMod(vehicle, 40),
 | 
						|
    modStruts = GetVehicleMod(vehicle, 41),
 | 
						|
    modArchCover = GetVehicleMod(vehicle, 42),
 | 
						|
    modAerials = GetVehicleMod(vehicle, 43),
 | 
						|
    modTrimB = GetVehicleMod(vehicle, 44),
 | 
						|
    modTank = GetVehicleMod(vehicle, 45),
 | 
						|
    modWindows = GetVehicleMod(vehicle, 46),
 | 
						|
    modDoorR = GetVehicleMod(vehicle, 47),
 | 
						|
    modLivery = modLivery,
 | 
						|
    modRoofLivery = GetVehicleRoofLivery(vehicle),
 | 
						|
    modLightbar = GetVehicleMod(vehicle, 49),
 | 
						|
    bulletProofTyres = not GetVehicleTyresCanBurst(vehicle),
 | 
						|
    driftTyres = GetGameBuildNumber() >= 2372 and GetDriftTyresEnabled(vehicle),
 | 
						|
    xenonCustomColorEnabled = xenonCustomColorEnabled,
 | 
						|
    xenonCustomColor = xenonCustomColor,
 | 
						|
 | 
						|
    -- ESX COMPATIBILITY
 | 
						|
    doorsBroken = doorsBroken,
 | 
						|
    windowsBroken = windowsBroken,
 | 
						|
    tyreBurst = tyreBurst,
 | 
						|
    tyresCanBurst = GetVehicleTyresCanBurst(vehicle),
 | 
						|
    customPrimaryColor = customPrimaryColor,
 | 
						|
    customSecondaryColor = customSecondaryColor,
 | 
						|
    customXenonColor = customXenonColor,
 | 
						|
    modCustomFrontWheels = GetVehicleModVariation(vehicle, 23),
 | 
						|
    modCustomBackWheels = GetVehicleModVariation(vehicle, 24),
 | 
						|
 | 
						|
    -- QB COMPATIBILITY
 | 
						|
    modKit17 = GetVehicleMod(vehicle, 17),
 | 
						|
    modKit19 = GetVehicleMod(vehicle, 19),
 | 
						|
    modKit21 = GetVehicleMod(vehicle, 21),
 | 
						|
    modKit47 = GetVehicleMod(vehicle, 47),
 | 
						|
    modKit49 = GetVehicleMod(vehicle, 49),
 | 
						|
    liveryRoof = GetVehicleRoofLivery(vehicle),
 | 
						|
  }
 | 
						|
 | 
						|
  if withStatebags then
 | 
						|
    local statebag = Entity(vehicle).state
 | 
						|
    local statebagProps = {
 | 
						|
      -- Custom menu properties
 | 
						|
      primarySecondarySync = statebag.primarySecondarySync,
 | 
						|
      disablePearl = statebag.disablePearl,
 | 
						|
 | 
						|
      -- Stancing
 | 
						|
      enableStance = statebag.enableStance or false,
 | 
						|
      wheelsAdjIndv = statebag.wheelsAdjIndv or false,
 | 
						|
      defaultStance = statebag.defaultStance or getVehicleDefaultStance(vehicle),
 | 
						|
      stance = statebag.stance or getVehicleDefaultStance(vehicle),
 | 
						|
 | 
						|
      -- Lighting Controller
 | 
						|
      lcInstalled = statebag.lightingControllerInstalled,
 | 
						|
      lcXenons = statebag.xenons,
 | 
						|
      lcUnderglowDirections = statebag.underglowDirections,
 | 
						|
      lcUnderglow = statebag.underglow,
 | 
						|
 | 
						|
      -- Tuning
 | 
						|
      tuningConfig = statebag.tuningConfig,
 | 
						|
 | 
						|
      -- Servicing
 | 
						|
      servicingData = statebag.servicingData,
 | 
						|
 | 
						|
      -- NOS
 | 
						|
      nitrousInstalledBottles = statebag.nitrousInstalledBottles,
 | 
						|
      nitrousFilledBottles = statebag.nitrousFilledBottles,
 | 
						|
      nitrousCapacity = statebag.nitrousCapacity,
 | 
						|
    }
 | 
						|
 | 
						|
    props = tableConcat(props, statebagProps)
 | 
						|
  end
 | 
						|
 | 
						|
  return props
 | 
						|
end
 | 
						|
 | 
						|
exports("getVehicleProperties", getVehicleProperties)
 | 
						|
 | 
						|
---@param vehicle integer
 | 
						|
---@param props table
 | 
						|
---@param withStatebags? boolean
 | 
						|
function setVehicleProperties(vehicle, props, withStatebags)
 | 
						|
  if not DoesEntityExist(vehicle) or not props or type(props) ~= "table" then return false end
 | 
						|
  
 | 
						|
  local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
 | 
						|
  local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
 | 
						|
 | 
						|
  SetVehicleModKit(vehicle, 0)
 | 
						|
  -- SetVehicleAutoRepairDisabled(vehicle, true)
 | 
						|
 | 
						|
  -- ESX COMPATIBILITY
 | 
						|
  if props.windowsBroken ~= nil then
 | 
						|
    for k, v in pairs(props.windowsBroken) do
 | 
						|
      if v then
 | 
						|
        k = tonumber(k)
 | 
						|
        if k then
 | 
						|
          RemoveVehicleWindow(vehicle, k)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.doorsBroken ~= nil then
 | 
						|
    for k, v in pairs(props.doorsBroken) do
 | 
						|
      if v then
 | 
						|
        k = tonumber(k)
 | 
						|
        if k then
 | 
						|
          SetVehicleDoorBroken(vehicle, k, true)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tyreBurst ~= nil then
 | 
						|
    for k, v in pairs(props.tyreBurst) do
 | 
						|
      if v then
 | 
						|
        k = tonumber(k)
 | 
						|
        if k then
 | 
						|
          SetVehicleTyreBurst(vehicle, k, true, 1000.0)
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tyresCanBurst ~= nil then
 | 
						|
    SetVehicleTyresCanBurst(vehicle, props.tyresCanBurst)
 | 
						|
  end
 | 
						|
 | 
						|
  -- if props.customPrimaryColor ~= nil then
 | 
						|
  --   SetVehicleCustomPrimaryColour(vehicle, props.customPrimaryColor[1], props.customPrimaryColor[2], props.customPrimaryColor[3])
 | 
						|
  -- end
 | 
						|
  
 | 
						|
  -- if props.customSecondaryColor ~= nil then
 | 
						|
  --   SetVehicleCustomSecondaryColour(vehicle, props.customSecondaryColor[1], props.customSecondaryColor[2], props.customSecondaryColor[3])
 | 
						|
  -- end
 | 
						|
 | 
						|
  -- if props.customXenonColor ~= nil then
 | 
						|
  --   SetVehicleXenonLightsCustomColor(vehicle, props.customXenonColor[1], props.customXenonColor[2], props.customXenonColor[3])
 | 
						|
  -- end
 | 
						|
  -- END ESX COMPATIBILITY
 | 
						|
 | 
						|
  -- QB COMPATIBILITY
 | 
						|
  if props.modKit17 then
 | 
						|
    SetVehicleMod(vehicle, 17, props.modKit17, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modKit19 then
 | 
						|
    SetVehicleMod(vehicle, 19, props.modKit19, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modKit21 then
 | 
						|
    SetVehicleMod(vehicle, 21, props.modKit21, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modKit47 then
 | 
						|
    SetVehicleMod(vehicle, 47, props.modKit47, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modKit49 then
 | 
						|
    SetVehicleMod(vehicle, 49, props.modKit49, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.liveryRoof then
 | 
						|
    SetVehicleRoofLivery(vehicle, props.liveryRoof)
 | 
						|
  end
 | 
						|
  -- END QB COMPATIBILITY
 | 
						|
 | 
						|
  if props.extras then
 | 
						|
    for id, enabled in pairs(props.extras) do
 | 
						|
      SetVehicleExtra(vehicle, tonumber(id) --[[@as integer]], not enabled) 
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.plate then
 | 
						|
    SetVehicleNumberPlateText(vehicle, props.plate)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.plateIndex then
 | 
						|
    SetVehicleNumberPlateTextIndex(vehicle, props.plateIndex)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.bodyHealth then
 | 
						|
    SetVehicleBodyHealth(vehicle, props.bodyHealth + 0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.engineHealth then
 | 
						|
    SetVehicleEngineHealth(vehicle, props.engineHealth + 0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tankHealth then
 | 
						|
    SetVehiclePetrolTankHealth(vehicle, props.tankHealth + 0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.fuelLevel then
 | 
						|
    SetVehicleFuelLevel(vehicle, props.fuelLevel + 0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.oilLevel then
 | 
						|
    SetVehicleOilLevel(vehicle, props.oilLevel + 0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.dirtLevel then
 | 
						|
    SetVehicleDirtLevel(vehicle, props.dirtLevel + 0.0)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.color1 then
 | 
						|
    if type(props.color1) == "number" then
 | 
						|
      ClearVehicleCustomPrimaryColour(vehicle)
 | 
						|
      SetVehicleColours(vehicle, props.color1 --[[@as number]], type(colorSecondary) == "number" and colorSecondary or 0 --[[@as number]])
 | 
						|
    else
 | 
						|
      if props.paintType1 then SetVehicleModColor_1(vehicle, props.paintType1, 0, 0) end
 | 
						|
      ClearVehicleCustomPrimaryColour(vehicle)
 | 
						|
      SetVehicleCustomPrimaryColour(vehicle, props.color1[1], props.color1[2], props.color1[3])
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.color2 then
 | 
						|
    if type(props.color2) == "number" then
 | 
						|
      ClearVehicleCustomSecondaryColour(vehicle)
 | 
						|
 | 
						|
      local primaryColour = props.color1 or colorPrimary
 | 
						|
      SetVehicleColours(vehicle, type(primaryColour) == "number" and primaryColour or 0 --[[@as number]], props.color2 --[[@as number]])
 | 
						|
    else
 | 
						|
      if props.paintType2 then SetVehicleModColor_2(vehicle, props.paintType2, 0) end
 | 
						|
      ClearVehicleCustomSecondaryColour(vehicle)
 | 
						|
      SetVehicleCustomSecondaryColour(vehicle, props.color2[1], props.color2[2], props.color2[3])
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.pearlescentColor or props.wheelColor then
 | 
						|
    SetVehicleExtraColours(vehicle, props.pearlescentColor or pearlescentColor, props.wheelColor or wheelColor)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.interiorColor then
 | 
						|
    SetVehicleInteriorColor(vehicle, props.interiorColor)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.dashboardColor then
 | 
						|
    SetVehicleDashboardColor(vehicle, props.dashboardColor)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.wheels then
 | 
						|
    SetVehicleWheelType(vehicle, props.wheels)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.wheelSize then
 | 
						|
    SetVehicleWheelSize(vehicle, props.wheelSize)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.wheelWidth then
 | 
						|
    SetVehicleWheelWidth(vehicle, props.wheelWidth)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.windowTint then
 | 
						|
    SetVehicleWindowTint(vehicle, props.windowTint)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.windowStatus then
 | 
						|
    for windowIndex, smashWindow in pairs(props.windowStatus) do
 | 
						|
      if not smashWindow then
 | 
						|
        RemoveVehicleWindow(vehicle, windowIndex)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.doorStatus then
 | 
						|
    for doorIndex, breakDoor in pairs(props.doorStatus) do
 | 
						|
      if breakDoor then
 | 
						|
        if type(doorIndex) == "string" then doorIndex = tonumber(doorIndex) or 0 end
 | 
						|
        SetVehicleDoorBroken(vehicle, doorIndex, true)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tireHealth then
 | 
						|
    for wheelIndex, health in pairs(props.tireHealth) do
 | 
						|
      SetVehicleWheelHealth(vehicle, wheelIndex, health)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tireBurstState then
 | 
						|
    for wheelIndex, burstState in pairs(props.tireBurstState) do
 | 
						|
      if burstState then
 | 
						|
        if type(wheelIndex) == "string" then wheelIndex = tonumber(wheelIndex) or 0 end
 | 
						|
        SetVehicleTyreBurst(vehicle, wheelIndex, false, 1000.0)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tireBurstCompletely then
 | 
						|
    for wheelIndex, burstState in pairs(props.tireBurstCompletely) do
 | 
						|
      if burstState then
 | 
						|
        if type(wheelIndex) == "string" then wheelIndex = tonumber(wheelIndex) or 0 end 
 | 
						|
        SetVehicleTyreBurst(vehicle, wheelIndex, true, 1000.0)
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.neonEnabled then
 | 
						|
    for i = 1, #props.neonEnabled do
 | 
						|
      SetVehicleNeonLightEnabled(vehicle, i - 1, props.neonEnabled[i])
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if props.neonColor then
 | 
						|
    SetVehicleNeonLightsColour(vehicle, props.neonColor[1], props.neonColor[2], props.neonColor[3])
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSmokeEnabled ~= nil then
 | 
						|
    ToggleVehicleMod(vehicle, 20, props.modSmokeEnabled)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.tyreSmokeColor then
 | 
						|
    SetVehicleTyreSmokeColor(vehicle, props.tyreSmokeColor[1], props.tyreSmokeColor[2], props.tyreSmokeColor[3])
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSpoilers then
 | 
						|
    SetVehicleMod(vehicle, 0, props.modSpoilers, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modFrontBumper then
 | 
						|
    SetVehicleMod(vehicle, 1, props.modFrontBumper, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modRearBumper then
 | 
						|
    SetVehicleMod(vehicle, 2, props.modRearBumper, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSideSkirt then
 | 
						|
    SetVehicleMod(vehicle, 3, props.modSideSkirt, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modExhaust then
 | 
						|
    SetVehicleMod(vehicle, 4, props.modExhaust, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modFrame then
 | 
						|
    SetVehicleMod(vehicle, 5, props.modFrame, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modGrille then
 | 
						|
    SetVehicleMod(vehicle, 6, props.modGrille, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modHood then
 | 
						|
    SetVehicleMod(vehicle, 7, props.modHood, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modFender then
 | 
						|
    SetVehicleMod(vehicle, 8, props.modFender, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modRightFender then
 | 
						|
    SetVehicleMod(vehicle, 9, props.modRightFender, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modRoof then
 | 
						|
    SetVehicleMod(vehicle, 10, props.modRoof, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modEngine then
 | 
						|
    SetVehicleMod(vehicle, 11, props.modEngine, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modBrakes then
 | 
						|
    SetVehicleMod(vehicle, 12, props.modBrakes, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modTransmission then
 | 
						|
    SetVehicleMod(vehicle, 13, props.modTransmission, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modHorns then
 | 
						|
    SetVehicleMod(vehicle, 14, props.modHorns, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSuspension then
 | 
						|
    SetVehicleMod(vehicle, 15, props.modSuspension, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modArmor then
 | 
						|
    SetVehicleMod(vehicle, 16, props.modArmor, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modNitrous then
 | 
						|
    SetVehicleMod(vehicle, 17, props.modNitrous, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modTurbo ~= nil then
 | 
						|
    ToggleVehicleMod(vehicle, 18, props.modTurbo)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSubwoofer ~= nil then
 | 
						|
    ToggleVehicleMod(vehicle, 19, props.modSubwoofer)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modHydraulics ~= nil then
 | 
						|
    ToggleVehicleMod(vehicle, 21, props.modHydraulics)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modXenon ~= nil then
 | 
						|
    ToggleVehicleMod(vehicle, 22, props.modXenon)
 | 
						|
  end
 | 
						|
 | 
						|
  if type(props.xenonColor) == "table" then
 | 
						|
    props.xenonCustomColorEnabled = true
 | 
						|
    props.xenonCustomColor = props.xenonColor
 | 
						|
  end
 | 
						|
 | 
						|
  if props.xenonCustomColorEnabled and type(props.xenonCustomColor) == "table" then
 | 
						|
    SetVehicleXenonLightsCustomColor(
 | 
						|
      vehicle,
 | 
						|
      props.xenonCustomColor[1], props.xenonCustomColor[2], props.xenonCustomColor[3]
 | 
						|
    )
 | 
						|
  elseif props.xenonColor and type(props.xenonColor) == "number" then
 | 
						|
    SetVehicleXenonLightsColor(vehicle, props.xenonColor)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modFrontWheels then
 | 
						|
    SetVehicleMod(vehicle, 23, props.modFrontWheels, props.modCustomTiresF or props.modCustomFrontWheels) -- ESX BC: modCustomFrontWheels
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modBackWheels then
 | 
						|
    SetVehicleMod(vehicle, 24, props.modBackWheels, props.modCustomTiresR or props.modCustomBackWheels) -- ESX BC: modCustomBackWheels
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modPlateHolder then
 | 
						|
    SetVehicleMod(vehicle, 25, props.modPlateHolder, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modVanityPlate then
 | 
						|
    SetVehicleMod(vehicle, 26, props.modVanityPlate, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modTrimA then
 | 
						|
    SetVehicleMod(vehicle, 27, props.modTrimA, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modOrnaments then
 | 
						|
    SetVehicleMod(vehicle, 28, props.modOrnaments, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modDashboard then
 | 
						|
    SetVehicleMod(vehicle, 29, props.modDashboard, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modDial then
 | 
						|
    SetVehicleMod(vehicle, 30, props.modDial, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modDoorSpeaker then
 | 
						|
    SetVehicleMod(vehicle, 31, props.modDoorSpeaker, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSeats then
 | 
						|
    SetVehicleMod(vehicle, 32, props.modSeats, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSteeringWheel then
 | 
						|
    SetVehicleMod(vehicle, 33, props.modSteeringWheel, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modShifterLeavers then
 | 
						|
    SetVehicleMod(vehicle, 34, props.modShifterLeavers, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modAPlate then
 | 
						|
    SetVehicleMod(vehicle, 35, props.modAPlate, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modSpeakers then
 | 
						|
    SetVehicleMod(vehicle, 36, props.modSpeakers, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modTrunk then
 | 
						|
    SetVehicleMod(vehicle, 37, props.modTrunk, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modHydrolic then
 | 
						|
    SetVehicleMod(vehicle, 38, props.modHydrolic, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modEngineBlock then
 | 
						|
    SetVehicleMod(vehicle, 39, props.modEngineBlock, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modAirFilter then
 | 
						|
    SetVehicleMod(vehicle, 40, props.modAirFilter, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modStruts then
 | 
						|
    SetVehicleMod(vehicle, 41, props.modStruts, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modArchCover then
 | 
						|
    SetVehicleMod(vehicle, 42, props.modArchCover, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modAerials then
 | 
						|
    SetVehicleMod(vehicle, 43, props.modAerials, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modTrimB then
 | 
						|
    SetVehicleMod(vehicle, 44, props.modTrimB, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modTank then
 | 
						|
    SetVehicleMod(vehicle, 45, props.modTank, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modWindows then
 | 
						|
    SetVehicleMod(vehicle, 46, props.modWindows, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modDoorR then
 | 
						|
    SetVehicleMod(vehicle, 47, props.modDoorR, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modLivery then
 | 
						|
    SetVehicleMod(vehicle, 48, props.modLivery, false)
 | 
						|
    SetVehicleLivery(vehicle, props.modLivery)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modRoofLivery then
 | 
						|
    SetVehicleRoofLivery(vehicle, props.modRoofLivery)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.modLightbar then
 | 
						|
    SetVehicleMod(vehicle, 49, props.modLightbar, false)
 | 
						|
  end
 | 
						|
 | 
						|
  if props.bulletProofTyres ~= nil then
 | 
						|
    SetVehicleTyresCanBurst(vehicle, not props.bulletProofTyres)
 | 
						|
  end
 | 
						|
 | 
						|
  if GetGameBuildNumber() >= 2372 and props.driftTyres then
 | 
						|
    SetDriftTyresEnabled(vehicle, true)
 | 
						|
  end
 | 
						|
 | 
						|
  if withStatebags then
 | 
						|
    SetTimeout(1000, function()
 | 
						|
      setStatebagsFromProps(vehicle, props)
 | 
						|
    end)
 | 
						|
  end
 | 
						|
 | 
						|
  return not NetworkGetEntityIsNetworked(vehicle) or NetworkGetEntityOwner(vehicle) == cache.playerId
 | 
						|
end
 | 
						|
 | 
						|
exports("setVehicleProperties", setVehicleProperties)
 | 
						|
 | 
						|
---This is for some (potential) integrations, not sure if it's being used right now
 | 
						|
---@param vehicle integer
 | 
						|
function getVehicleStatebagProperties(vehicle)
 | 
						|
  if not DoesEntityExist(vehicle) then return false end
 | 
						|
  
 | 
						|
  local statebag = Entity(vehicle).state
 | 
						|
 | 
						|
  return {
 | 
						|
    -- Custom menu properties
 | 
						|
    primarySecondarySync = statebag.primarySecondarySync,
 | 
						|
    disablePearl = statebag.disablePearl,
 | 
						|
 | 
						|
    -- Stancing
 | 
						|
    enableStance = statebag.enableStance or false,
 | 
						|
    wheelsAdjIndv = statebag.wheelsAdjIndv or false,
 | 
						|
    defaultStance = statebag.defaultStance or getVehicleDefaultStance(vehicle),
 | 
						|
    stance = statebag.stance or getVehicleDefaultStance(vehicle),
 | 
						|
 | 
						|
    -- Lighting Controller
 | 
						|
    lcInstalled = statebag.lightingControllerInstalled,
 | 
						|
    lcXenons = statebag.xenons,
 | 
						|
    lcUnderglowDirections = statebag.underglowDirections,
 | 
						|
    lcUnderglow = statebag.underglow,
 | 
						|
 | 
						|
    -- Tuning
 | 
						|
    tuningConfig = statebag.tuningConfig,
 | 
						|
 | 
						|
    -- Servicing
 | 
						|
    servicingData = statebag.servicingData,
 | 
						|
 | 
						|
    -- NOS
 | 
						|
    nitrousInstalledBottles = statebag.nitrousInstalledBottles,
 | 
						|
    nitrousFilledBottles = statebag.nitrousFilledBottles,
 | 
						|
    nitrousCapacity = statebag.nitrousCapacity
 | 
						|
  }
 | 
						|
end
 | 
						|
 | 
						|
exports("getVehicleStatebagProperties", getVehicleStatebagProperties)
 | 
						|
 | 
						|
---This is for some (potential) integrations, not sure if it's being used right now
 | 
						|
---@param vehicle integer
 | 
						|
---@param props table
 | 
						|
function setVehicleStatebagProperties(vehicle, props)
 | 
						|
  if not DoesEntityExist(vehicle) or not props or type(props) ~= "table" then return false end
 | 
						|
 | 
						|
  setStatebagsFromProps(vehicle, props)
 | 
						|
  return true
 | 
						|
end
 | 
						|
 | 
						|
exports("setVehicleStatebagProperties", setVehicleStatebagProperties)
 | 
						|
 | 
						|
-- 
 | 
						|
-- Apply vehicle props statebag for setting vehicleProperties on ent owner
 | 
						|
-- 
 | 
						|
 | 
						|
---@param bagName string
 | 
						|
---@param props table
 | 
						|
AddStateBagChangeHandler("applyVehicleProps", "", function(bagName, _, props)
 | 
						|
  if not props or type(props) ~= "table" then return false end
 | 
						|
 | 
						|
  local vehicle = GetEntityFromStateBagName(bagName)
 | 
						|
  if not vehicle or vehicle == 0 then return end
 | 
						|
 | 
						|
  SetTimeout(0, function()
 | 
						|
    local state, attempts = Entity(vehicle).state, 0
 | 
						|
 | 
						|
    while attempts < 10 do
 | 
						|
      if NetworkGetEntityOwner(vehicle) == cache.playerId and setVehicleProperties(vehicle, props, true) then
 | 
						|
        state:set("applyVehicleProps", nil, true)
 | 
						|
        break
 | 
						|
      end
 | 
						|
 | 
						|
      attempts += 1
 | 
						|
      Wait(100)
 | 
						|
    end
 | 
						|
  end)
 | 
						|
end)
 | 
						|
 | 
						|
--
 | 
						|
-- Whenever you sit in a vehicle, check if there is statebag data available in cache or DB and set it
 | 
						|
-- 
 | 
						|
 | 
						|
local vehiclePlate = nil
 | 
						|
 | 
						|
local function onEnterVehicle(vehicle)
 | 
						|
  -- Save DB data of last vehicle when getting out of a vehicle
 | 
						|
  if vehiclePlate then
 | 
						|
    lib.callback.await("jg-mechanic:server:save-veh-statebag-data-to-db", false, vehiclePlate, true)
 | 
						|
  end
 | 
						|
 | 
						|
  if not vehicle or vehicle == 0 then
 | 
						|
    vehiclePlate = nil
 | 
						|
    return
 | 
						|
  end
 | 
						|
 | 
						|
  -- New vehicle
 | 
						|
  SetTimeout(1000, function()
 | 
						|
    vehiclePlate = Framework.Client.GetPlate(vehicle)
 | 
						|
    lib.callback.await("jg-mechanic:server:retrieve-and-apply-veh-statebag-data", false, VehToNet(vehicle), getVehicleDefaultStance(vehicle), getBaseVehicleHandling(vehicle))
 | 
						|
  end)
 | 
						|
end
 | 
						|
 | 
						|
lib.onCache("vehicle", onEnterVehicle)
 | 
						|
if cache.vehicle then onEnterVehicle(cache.vehicle) end -- In case of script restart, lib.onCache does not run if you're already sat in a vehicle |