Add vehicle properties system and update attributions

Introduces a comprehensive vehicle properties handler in lib/vehicles/client.lua, inspired by ESX, QB-Core, and ox_lib frameworks. Updates Attributions.md to document the new vehicle system, clarify licensing, and improve formatting. Registers Vehicles in lib/init.lua for client use.
This commit is contained in:
MrNewb committed 2025-09-10 11:07:58 -04:00
1 parent 66df77cc3f
commit f472232273
3 files changed
+581 -46

No files matched your search

+70 -46
View File
@@ -1,98 +1,122 @@
# Attributions
> **Community Bridge** This project incorporates code from several outstanding libraries and resources, all licensed under GPLv3. We're grateful to the talented developers who made their work available to the community.
> **Community Bridge** incorporates code from several outstanding libraries and resources, all licensed under GPLv3. We’re grateful to the talented developers who made their work available to the community.
---
## Libraries & Resources
### r\_bridge
**Purpose:** Code for codem-inventory bridging, and initial targeting
**Repository:** [r\_bridge](https://github.com/rumaier/r_bridge)
<details>
<summary>Implementation Details</summary>
<summary><strong>r_bridge</strong></summary>
**Purpose:** Code for codem-inventory bridging, and initial targeting
**Repository:** [r_bridge](https://github.com/rumaier/r_bridge)
**Code we use:**
* Inventory bridging code for codem-inventory integration
* Targeting system foundation
- Inventory bridging code for codem-inventory integration
- Targeting system foundation
**Modifications made:**
* Adapted inventory bridge for codem compatibility in alternative structure
- Adapted inventory bridge for codem compatibility in alternative structure
</details>
---
### ox\_lib
**Purpose:** External compatibility and architectural inspiration
**Repository:** [ox\_lib](https://github.com/overextended/ox_lib)
<details>
<summary>Implementation Details</summary>
<summary><strong>ox_lib</strong></summary>
**Purpose:** Architectural inspiration
**Repository:** [ox_lib](https://github.com/overextended/ox_lib)
**Compatibility features:**
* External resource integration for raycasting utilities
* Shared conventions
- External resource integration for raycasting utilities
- Shared conventions
**Implementation approach:**
* No direct code usage - maintains compatibility as external resource
* Follows ox\_lib conventions for seamless integration
* Provides bridge compatibility for servers using ox\_lib ecosystem
- No direct code usage — maintains compatibility as external resource
- Follows ox_lib conventions for seamless integration
- Provides bridge compatibility for servers using ox_lib ecosystem
</details>
---
### renewed\_lib
**Purpose:** Object placer functionality
**Repository:** [renewed\_lib](https://github.com/Renewed-Scripts/Renewed-Lib)
<details>
<summary>Implementation Details</summary>
<summary><strong>renewed_lib</strong></summary>
**Purpose:** Object placer functionality
**Repository:** [renewed_lib](https://github.com/Renewed-Scripts/Renewed-Lib)
**Code we use:**
* Object placement system
- Object placement system
**Modifications made:**
* Updated variable naming for consistency
* Added missing parameters for native functions
* Updated deprecated ox\_lib raycast camera export
* Enhanced showtext UI to work with multiple systems
* Moved placement text to locales for internationalization
* Replaced ox\_lib model request exports with our bridge functions
- Updated variable naming for consistency
- Added missing parameters for native functions
- Updated deprecated ox_lib raycast camera export
- Enhanced showtext UI to work with multiple systems
- Moved placement text to locales for internationalization
- Replaced ox_lib model request exports with our bridge functions
</details>
---
### duff
<details>
<summary><strong>duff</strong></summary>
**Purpose:** Version checker system and update notifications
**Purpose:** Version checker system and update notifications
**Repository:** [duff](https://github.com/DonHulieo/duff/blob/d89ed3b0051194babf5711114a0c437d4e41f433/server/init.lua#L10C1-L28C4)
<details>
<summary>Implementation Details</summary>
**Code we use:**
* Version checker formatting patterns
* Repository information handling
- Version checker formatting patterns
- Repository information handling
**Modifications made:**
* Removed unnecessary variables
* Enhanced to pull repository information from passed strings
* Adapted print formatting for our use case
- Removed unnecessary variables
- Enhanced to pull repository information from passed strings
- Adapted print formatting for our use case
</details>
---
<details>
<summary><strong>Vehicle Properties System</strong></summary>
**Purpose:** Set and manage vehicle properties in the game world, inspired by multiple community frameworks.
**Repositories referenced:**
- [ESX-Framework (ESX.Game.SetVehicleProperties)](https://github.com/esx-framework/es_extended)
- [QB-Core (qb-core)](https://github.com/qbcore-framework/qb-core)
- [ox_lib](https://github.com/overextended/ox_lib) (architectural inspiration and modifications)
**Code origin and inspiration:**
- Primarily draws on concepts and structures from ESX and QB-Core, with ox_lib serving as architectural inspiration.
- ESX and QB-Core implementations use similar approaches for setting vehicle mods, colors, damages, and extras.
- ox_lib adapts and extends these approaches within its framework, showing overlapping code patterns.
**Modifications made:**
- Combined and refactored logic to suit Community Bridge project needs.
- Adapted license to GPLv3 for compatibility and open-source compliance.
- Added explicit handling of custom colors, mod toggles, and damage states.
**Licensing notes:**
- Original ESX and QB-Core frameworks are GPLv3 licensed.
- ox_lib is LGPL licensed, used here as architectural inspiration only.
- This project’s vehicle properties code inherits GPLv3 licensing consistent with ESX/QB-Core, honoring their licensing terms and attributions.
</details>
@@ -100,7 +124,7 @@
## Special Thanks
A heartfelt thank you to all the creators and maintainers of these libraries, bridges, and resources. Your dedication to open-source development and the FiveM community makes projects like Community Bridge possible.
A heartfelt thank you to all creators and maintainers of these libraries, bridges, and resources. Your dedication to open-source development and the FiveM community makes projects like Community Bridge possible.
Your willingness to share knowledge and code under GPLv3 licensing enables the entire community to build better, more compatible systems together.
@@ -114,4 +138,4 @@ For detailed license information, see the [LICENSE](LICENSE) file in the project
---
> *"If I have seen further it is by standing on the shoulders of Giants."* - Isaac Newton
> *"If I have seen further it is by standing on the shoulders of Giants."* – Isaac Newton
+1
View File
@@ -80,6 +80,7 @@ cLib.Anim = Anim or Require("lib/anim/client/client.lua")
cLib.Cutscene = Cutscene or Require("lib/cutscenes/client/cutscene.lua")
cLib.Particle = Particle or Require("lib/particles/client/particles.lua")
cLib.Entity = ClientEntity or Require("lib/entities/client/client_entity.lua")
cLib.Vehicles = Vehicles or Require("lib/vehicles/client.lua")
-- Deprecated
cLib.ClientEntity = cLib.Entity
+510
View File
@@ -0,0 +1,510 @@
---@diagnostic disable: duplicate-set-field
Vehicles = Vehicles or {}
-- Vehicle properties setter function
--
-- Inspired by and derived from vehicle property handlers in:
-- ESX Framework (https://github.com/esx-framework/esx_core) [License: GPLv3]
-- QBCore Framework (https://github.com/qbcore-framework/qb-core) [License: GPLv3]
--
-- Note: The ox_lib version (https://github.com/overextended/ox_lib) [License: LGPLv3] also draws heavily from these projects.
--
-- This code is licensed under the GNU General Public License v3.0 (GPLv3).
-- You may use, modify, and distribute this code under the terms of the GPLv3.
-- See LICENSE file for full details.
if not DecorIsRegisteredAsType("Player_Vehicle", 3) then DecorRegister("Player_Vehicle", 3) end
---@alias RGBColor number[] RGB color array [r, g, b] where each component is 0-255
---@alias VehicleExtras table<number, number> Vehicle extras where key is extra ID and value is state (0=enabled, 1=disabled)
---@class VehicleProperties
---@field model? number Vehicle model hash
---@field plate? string License plate text
---@field plateIndex? number License plate style index (0-5)
---@field bodyHealth? number Body health (0-1000)
---@field engineHealth? number Engine health (0-1000)
---@field tankHealth? number Tank health (0-1000)
---@field fuelLevel? number Fuel level (0-100)
---@field oilLevel? number Oil level (0-100)
---@field dirtLevel? number Dirt level (0-15)
---@field paintType1? number Primary paint type
---@field paintType2? number Secondary paint type
---@field color1? number|RGBColor Primary color (color index or RGB values)
---@field color2? number|RGBColor Secondary color (color index or RGB values)
---@field pearlescentColor? number Pearlescent color index
---@field interiorColor? number Interior color index
---@field dashboardColor? number Dashboard color index
---@field wheelColor? number Wheel color index
---@field wheelWidth? number Wheel width
---@field wheelSize? number Wheel size
---@field wheels? number Wheel type
---@field windowTint? number Window tint level (0-6)
---@field xenonColor? number Xenon headlight color
---@field neonEnabled? boolean[] Neon light states [left, right, front, back]
---@field neonColor? RGBColor Neon light color RGB values
---@field extras? VehicleExtras Vehicle extras configuration
---@field tyreSmokeColor? RGBColor Tyre smoke color RGB values
---@field modSpoilers? number Spoiler modification (-1 to max)
---@field modFrontBumper? number Front bumper modification (-1 to max)
---@field modRearBumper? number Rear bumper modification (-1 to max)
---@field modSideSkirt? number Side skirt modification (-1 to max)
---@field modExhaust? number Exhaust modification (-1 to max)
---@field modFrame? number Frame modification (-1 to max)
---@field modGrille? number Grille modification (-1 to max)
---@field modHood? number Hood modification (-1 to max)
---@field modFender? number Fender modification (-1 to max)
---@field modRightFender? number Right fender modification (-1 to max)
---@field modRoof? number Roof modification (-1 to max)
---@field modEngine? number Engine modification (-1 to max)
---@field modBrakes? number Brakes modification (-1 to max)
---@field modTransmission? number Transmission modification (-1 to max)
---@field modSuspension? number Suspension modification (-1 to max)
---@field modArmor? number Armor modification (-1 to max)
---@field modNitrous? number Nitrous modification (-1 to max)
---@field modHorns? number Horn modification (-1 to max)
---@field modSubwoofer? number Subwoofer modification (-1 to max)
---@field modTurbo? boolean Turbo toggle
---@field modSmokeEnabled? boolean Tyre smoke toggle
---@field modHydraulics? boolean Hydraulics toggle
---@field modXenon? boolean Xenon lights toggle
---@field modFrontWheels? number Front wheels modification (-1 to max)
---@field modBackWheels? number Back wheels modification (-1 to max)
---@field modCustomTiresF? boolean Custom front tires enabled
---@field modCustomTiresR? boolean Custom rear tires enabled
---@field modPlateHolder? number Plate holder modification (-1 to max)
---@field modVanityPlate? number Vanity plate modification (-1 to max)
---@field modTrimA? number Trim A modification (-1 to max)
---@field modOrnaments? number Ornaments modification (-1 to max)
---@field modDashboard? number Dashboard modification (-1 to max)
---@field modDial? number Dial modification (-1 to max)
---@field modDoorSpeaker? number Door speaker modification (-1 to max)
---@field modSeats? number Seats modification (-1 to max)
---@field modSteeringWheel? number Steering wheel modification (-1 to max)
---@field modShifterLeavers? number Shifter levers modification (-1 to max)
---@field modAPlate? number A-plate modification (-1 to max)
---@field modSpeakers? number Speakers modification (-1 to max)
---@field modTrunk? number Trunk modification (-1 to max)
---@field modHydrolic? number Hydraulic modification (-1 to max)
---@field modEngineBlock? number Engine block modification (-1 to max)
---@field modAirFilter? number Air filter modification (-1 to max)
---@field modStruts? number Struts modification (-1 to max)
---@field modArchCover? number Arch cover modification (-1 to max)
---@field modAerials? number Aerials modification (-1 to max)
---@field modTrimB? number Trim B modification (-1 to max)
---@field modTank? number Tank modification (-1 to max)
---@field modWindows? number Windows modification (-1 to max)
---@field modDoorR? number Door R modification (-1 to max)
---@field modLivery? number Livery modification (-1 to max)
---@field modLightbar? number Lightbar modification (-1 to max)
---@field modRoofLivery? number Roof livery modification (-1 to max)
---@field livery? number Vehicle livery (-1 to max)
---@field windows? number[] Array of damaged window indices
---@field doors? number[] Array of damaged door indices
---@field tyres? table<number, number> Map of tyre index to damage state (1=burst, 2=destroyed)
---@field bulletProofTyres? boolean Bulletproof tyres enabled
---@field driftTyres? boolean Drift tyres enabled
---@field doorLockStatus? number Door lock status (0=none, 1=unlocked, 2=locked, 3=lockout, 4=can't enter)
---@field brokenWheels? number|number[] Single wheel index or array of wheel indices to break off (0-7)
-- Handle state bag changes for vehicle properties
AddStateBagChangeHandler('community_bridge:SetVehicleProperties', '', function(bagName, _, value)
if not value or not GetEntityFromStateBagName then return end
-- Wait for entity to exist with timeout
local entity = nil
local attempts = 0
local maxAttempts = 100 -- 10 seconds at 100ms intervals
while not entity and attempts < maxAttempts do
local tempEntity = GetEntityFromStateBagName(bagName)
if tempEntity and tempEntity > 0 and DoesEntityExist(tempEntity) then
entity = tempEntity
break
end
attempts = attempts + 1
Wait(100)
end
if not entity then return end
-- Apply vehicle properties from state bag (prevents infinite loops)
Vehicles.SetVehicleProperties(entity, value, true)
Wait(500)
-- Clear state if we own the entity (prevents accumulation)
if NetworkGetEntityOwner(entity) == PlayerId() then
Vehicles.SetVehicleProperties(entity, value, true)
Entity(entity).state:set('community_bridge:SetVehicleProperties', nil, false)
end
end)
local gameBuild = GetGameBuildNumber()
---Get comprehensive vehicle properties
---@param vehicle number The vehicle entity handle
---@return VehicleProperties|nil properties Table containing all vehicle properties, or nil if vehicle doesn't exist
function Vehicles.GetVehicleProperties(vehicle)
if not DoesEntityExist(vehicle) then return end
local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
local paintType1 = GetVehicleModColor_1(vehicle)
local paintType2 = GetVehicleModColor_2(vehicle)
-- Handle custom colors (can be either number or table)
local primaryColor = colorPrimary --[[@as number|table]]
local secondaryColor = colorSecondary --[[@as number|table]]
if GetIsVehiclePrimaryColourCustom(vehicle) then
local r, g, b = GetVehicleCustomPrimaryColour(vehicle)
primaryColor = { r, g, b }
end
if GetIsVehicleSecondaryColourCustom(vehicle) then
local r, g, b = GetVehicleCustomSecondaryColour(vehicle)
secondaryColor = { r, g, b }
end
-- Get vehicle extras
local extras = {}
for i = 1, 15 do
if DoesExtraExist(vehicle, i) then
extras[i] = IsVehicleExtraTurnedOn(vehicle, i) and 0 or 1
end
end
-- Get vehicle damage information
local damage = {
windows = {},
doors = {},
tyres = {},
brokenWheels = {},
}
-- Check window damage
local windows = 0
for i = 0, 7 do
RollUpWindow(vehicle, i)
if not IsVehicleWindowIntact(vehicle, i) then
windows += 1
damage.windows[windows] = i
end
end
-- Check door damage
local doors = 0
for i = 0, 5 do
if IsVehicleDoorDamaged(vehicle, i) then
doors += 1
damage.doors[doors] = i
end
end
-- Check tyre damage
for i = 0, 7 do
if IsVehicleTyreBurst(vehicle, i, false) then
damage.tyres[i] = IsVehicleTyreBurst(vehicle, i, true) and 2 or 1
end
end
-- Check broken wheels
for i = 0, 7 do
if IsVehicleWheelBrokenOff(vehicle, i) then
table.insert(damage.brokenWheels, i)
end
end
-- Get neon light status
local neons = {}
for i = 0, 3 do
neons[i + 1] = IsVehicleNeonLightEnabled(vehicle, i)
end
return {
model = GetEntityModel(vehicle),
plate = GetVehicleNumberPlateText(vehicle),
plateIndex = GetVehicleNumberPlateTextIndex(vehicle),
bodyHealth = math.floor(GetVehicleBodyHealth(vehicle) + 0.5),
engineHealth = math.floor(GetVehicleEngineHealth(vehicle) + 0.5),
tankHealth = math.floor(GetVehiclePetrolTankHealth(vehicle) + 0.5),
fuelLevel = math.floor(GetVehicleFuelLevel(vehicle) + 0.5),
oilLevel = math.floor(GetVehicleOilLevel(vehicle) + 0.5),
dirtLevel = math.floor(GetVehicleDirtLevel(vehicle) + 0.5),
paintType1 = paintType1,
paintType2 = paintType2,
color1 = primaryColor,
color2 = secondaryColor,
pearlescentColor = pearlescentColor,
interiorColor = GetVehicleInteriorColor(vehicle),
dashboardColor = GetVehicleDashboardColour(vehicle),
wheelColor = wheelColor,
wheelWidth = GetVehicleWheelWidth(vehicle),
wheelSize = GetVehicleWheelSize(vehicle),
wheels = GetVehicleWheelType(vehicle),
windowTint = GetVehicleWindowTint(vehicle),
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 = GetVehicleMod(vehicle, 48),
modRoofLivery = GetVehicleRoofLivery(vehicle),
modLightbar = GetVehicleMod(vehicle, 49),
livery = GetVehicleLivery(vehicle),
windows = damage.windows,
doors = damage.doors,
tyres = damage.tyres,
brokenWheels = damage.brokenWheels,
bulletProofTyres = GetVehicleTyresCanBurst(vehicle),
driftTyres = gameBuild >= 2372 and GetDriftTyresEnabled(vehicle),
doorLockStatus = GetVehicleDoorLockStatus(vehicle),
}
end
---Apply vehicle properties to a vehicle
---@param vehicle number The vehicle entity handle
---@param props VehicleProperties Table containing vehicle properties to apply
---@param fromStateBag? boolean Internal flag to prevent infinite loops when called from state bag handler
function Vehicles.SetVehicleProperties(vehicle, props, fromStateBag)
if not DoesEntityExist(vehicle) then return false end
local colorPrimary, colorSecondary = GetVehicleColours(vehicle)
local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle)
SetVehicleModKit(vehicle, 0)
-- Apply vehicle extras
if props.extras then
for id, disable in pairs(props.extras) do
local extraId = tonumber(id)
if extraId then
SetVehicleExtra(vehicle, extraId, disable == 1)
end
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
-- Apply vehicle colors
if props.color1 then
if type(props.color1) == 'number' then
ClearVehicleCustomPrimaryColour(vehicle)
SetVehicleColours(vehicle, props.color1 --[[@as number]], colorSecondary --[[@as number]])
else
if props.paintType1 then
SetVehicleModColor_1(vehicle, props.paintType1, 0, props.pearlescentColor or 0)
end
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)
SetVehicleColours(vehicle, props.color1 or colorPrimary --[[@as number]], props.color2 --[[@as number]])
else
if props.paintType2 then
SetVehicleModColor_2(vehicle, props.paintType2, 0)
end
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
-- Apply wheel properties
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
-- Apply window and lighting properties
if props.windowTint then SetVehicleWindowTint(vehicle, props.windowTint) 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
-- Apply vehicle damage
if props.windows then
for i = 1, #props.windows do
RemoveVehicleWindow(vehicle, props.windows[i])
end
end
if props.doors then
for i = 1, #props.doors do
SetVehicleDoorBroken(vehicle, props.doors[i], true)
end
end
if props.tyres then
for tyre, state in pairs(props.tyres) do
SetVehicleTyreBurst(vehicle, tonumber(tyre) --[[@as number]], state == 2, 1000.0)
end
end
if props.brokenWheels then
if type(props.brokenWheels) == 'number' then
BreakOffVehicleWheel(vehicle, props.brokenWheels --[[@as number]], false, true, true, false)
else
for i = 1, #props.brokenWheels do
BreakOffVehicleWheel(vehicle, props.brokenWheels[i], false, true, true, false)
end
end
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.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 props.modHorns then SetVehicleMod(vehicle, 14, props.modHorns, false) end
if props.xenonColor then SetVehicleXenonLightsColor(vehicle, props.xenonColor) end
if props.modFrontWheels then SetVehicleMod(vehicle, 23, props.modFrontWheels, props.modCustomTiresF) end
if props.modBackWheels then SetVehicleMod(vehicle, 24, props.modBackWheels, props.modCustomTiresR) 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) end
if props.modLightbar then SetVehicleMod(vehicle, 49, props.modLightbar, false) end
if props.modRoofLivery then SetVehicleRoofLivery(vehicle, props.modRoofLivery) end
if props.livery then SetVehicleLivery(vehicle, props.livery) end
if props.bulletProofTyres ~= nil then SetVehicleTyresCanBurst(vehicle, props.bulletProofTyres) end
if gameBuild >= 2372 and props.driftTyres then SetDriftTyresEnabled(vehicle, true) end
if props.doorLockStatus then
SetVehicleDoorsLocked(vehicle, props.doorLockStatus)
end
if not DecorExistOn(vehicle, "Player_Vehicle") then DecorSetInt(vehicle, "Player_Vehicle", -1) end
-- Only sync to other clients if not called from state bag AND we own the entity
if not fromStateBag and NetworkGetEntityIsNetworked(vehicle) and NetworkGetEntityOwner(vehicle) == PlayerId() then
Entity(vehicle).state:set('community_bridge:SetVehicleProperties', props, true)
if props.doorLockStatus then Entity(vehicle).state:set('door', tonumber(props.doorLockStatus), true) end
end
return true
end
return Vehicles