Config

-- ██╗ ██████╗██████╗ ██████╗         ███╗   ██╗██╗████████╗██████╗  ██████╗ 
-- ██║██╔════╝╚════██╗██╔══██╗        ████╗  ██║██║╚══██╔══╝██╔══██╗██╔═══██╗
-- ██║██║      █████╔╝██║  ██║        ██╔██╗ ██║██║   ██║   ██████╔╝██║   ██║
-- ██║██║      ╚═══██╗██║  ██║        ██║╚██╗██║██║   ██║   ██╔══██╗██║   ██║
-- ██║╚██████╗██████╔╝██████╔╝███████╗██║ ╚████║██║   ██║   ██║  ██║╚██████╔╝
-- ╚═╝ ╚═════╝╚═════╝ ╚═════╝ ╚══════╝╚═╝  ╚═══╝╚═╝   ╚═╝   ╚═╝  ╚═╝ ╚═════╝ 

Config = {
	-- Framework: 'auto' | 'esx' | 'qb'
	Framework = 'auto',

	-- Database mapping for vehicle storage
	-- For ESX default:
	DB = {
		table = 'owned_vehicles',
		plateColumn = 'plate',
		ownerColumn = 'owner',
		vehicleDataColumn = 'vehicle', -- JSON column to store ic3d_nitro
	},
	-- For QBCore (example), uncomment and adjust if your schema differs:
	-- DB = {
	-- 	table = 'player_vehicles',
	-- 	plateColumn = 'plate',
	-- 	ownerColumn = 'citizenid',
	-- 	vehicleDataColumn = 'mods',
	-- },

	weight_type = true, -- Weight handling (true = use kit weight in performance math)
	weight = 1.5, -- Base vehicle weight factor used in calcs
	jobonly = false, -- Restrict install/refill to a specific job?
	nitrojob = 'mechanic', -- Job name allowed when jobonly = true

	-- Installation requirement: require a tool item in inventory to install nitro
	
	requireInstallTool = true, -- Set requireInstallTool = true to enforce; specify the item name in installToolItem
	installToolItem = 'mechanic_tool', -- change to an item that exists in your ox_inventory (e.g., 'fixkit', 'wrench')

	-- If true, nitro can only be installed on vehicles that have a turbo installed/enabled
	requireTurboToInstall = false,

	nitro = { -- Nitro profiles (tuning multipliers)
		['default'] = { Power = 1.5, Torque = 1.5, label = 'Nitro System' },
	},
	
	bottle = { -- Bottle item setup (consumption tick and weight)
		['nitro_bottle'] = { tick = 0.05, weight = 30.0, label = 'Nitro Bottle' },
	},

	refill_item = 'nitroglycerine', -- The item required when refilling at stations

	-- Vehicle models blacklist: nitro cannot be installed or refilled on these models
	-- Accepts model names (strings) or hashes (numbers). Examples: 'RHINO', 'POLICE', `GetHashKey('RHINO')`
	vehicleBlacklist = {
		-- 'RHINO',
		-- 'POLICE',
		-- 0x2F03547B, -- example hashed model
	},
	enableRefill = true, -- Master toggle for allowing refills at stations
	refillMarker = false, -- Show 3D markers near refill stations (in-world prompts)
	refillTarget = true, -- Enable ox_target zones at stations
	spawnRefillProps = true, -- Spawn physical bottle props at station locations and attach ox_target to them
	refills = 100, -- Cost per nitro tick when refilling (server-side logic)

	-- Refill stations list (add as many as you want)
	-- job = 'all' means everyone can use; set to a job name to restrict
	refillstation = {
		[1] = {
			coord = vector3(-48.0936, -1037.8647, 28.3973),
			job = 'all',
			-- Optional prop spawn for ox_target interaction (Disable with spawnRefillProps = false [line 68])
			propModel = 'v_ind_cs_gascanister',   -- change to your preferred bottle prop model
			propHeading = 0.0,
			propOffset = vector3(0.0, 0.0, 0.0),
		},
		-- [2] = { coord = vector3(0.0, 0.0, 0.0), job = 'mechanic', propModel = 'prop_ld_jerrycan_01', propHeading = 180.0 },
	},

	-- Exhaust bones used for flames/trails
	exhaust_bones = {
		"exhaust",
		"exhaust_2",
		"exhaust_3",
		"exhaust_4",
	},

	-- Tail light bones (for light effects)
	tailights_bone = {
		"taillight_l",
		"taillight_r",
		-- "taillight_m",
	},

	-- Purge nozzle attachment points (front wheels look nice by default)
	purge_left_bone = "wheel_lf",
	purge_right_bone = "wheel_rf",

	nitroasset = "core", -- Base particle asset dictionary for nitro effects

	-- Controls
	controls = {
		boost = 21, -- default: LEFT SHIFT
	},

	-- Exhaust flame particle and size
	exhaust_particle_name = "veh_backfire",   -- default: "veh_backfire"
	exhaust_flame_size = 1.3,

	-- Trail particle and size (color tinting may be limited by GTA assets)
	trail_particle_name = "veh_light_red_trail",
	trail_size = 1.00,

	bannedindex = -1, -- Internal index guard (leave as -1)

	
	enablePurge = true, -- Master toggle: enable/disable purge jets when the vehicle is stationary
	
	purgeUsesNitro = true, -- If true, stationary purge consumes nitro

	-- Purge particle name
	purge_particle_name = "ent_sht_steam",   -- default: "ent_sht_steam"
	purge_asset = nil, -- Optional: override asset for purge; falls back to nitroasset when nil
	purge_size = 1.0, -- Purge nozzle jet size
	purge_color = { r = 55, g = 255, b = 55 }, -- Default purge color (0-255) and alpha (0.0 - 1.0)
	purge_alpha = 1.0,

	-- Gradient purge (animated between color A and B) — client can switch mode per vehicle
	purge_gradient = {
		enabled = true,           -- allow gradient mode
		speed = 0.01,            -- cycle speed (suggested 0.002 .. 0.04)
		color_b = { r = 170, g = 0, b = 255 },
		mode = 'solid',          -- 'solid' or 'gradient' default
	},

	enablePurgeRemote = true, -- Allow opening the Purge Remote UI (requires an item wired to export 'ic3d_nitro.usePurgeRemote')

	-- Performance tuning knobs
	performance = {
		-- How often (ms) to push state bag updates and server consumption during boost (higher = fewer updates)
		statePushIntervalMs = 200,
		-- How often (ms) to update the NUI HUD while boosting
		hudUpdateMs = 100,
		-- When true, only apply cheat power each tick if the vehicle has no turbo; when false, always apply
		applyCheatPowerOnlyNoTurbo = true,
	},

	-- Progress UI settings for time-based actions (installation/refill, etc.)
	-- If useOxLibProgress = true and ox_lib is running, an ox_lib progress bar will be used instead of Busyspinner.
	progress = {
		useOxLibProgress = true,  -- if true and ox_lib is available, use its progressBar
		refillDuration = 3000,    -- ms for refill action
		installDuration = 2500,   -- reserved for future install action
		labelRefill = 'Refilling nitro...',
	},

	-- Debug / developer options
	debug = {
		enableTestCommands = false, -- when true, enables /giveme_nitro for quick testing
		debugPrints = false,       -- when true, emit verbose debug logs to console
	},
}

-- Helper export (used elsewhere to read nitro profiles)
exports('nitros', function()
	return Config.nitro
end)

-- Unified notification helper available on both server and client
-- Server: Config.Notify(source, message, type)
-- Client: Config.Notify(message, type)
if IsDuplicityVersion() then
	function Config.Notify(src, msg, ntype)
		ntype = ntype or 'inform'
		if GetResourceState and GetResourceState('ox_lib') == 'started' then
			TriggerClientEvent('ox_lib:notify', src, { description = tostring(msg), type = ntype })
		else
			TriggerClientEvent('esx:showNotification', src, tostring(msg))
		end
	end
else
	function Config.Notify(msg, ntype)
		ntype = ntype or 'inform'
		local oxlib = rawget(_G, 'lib')
		if oxlib and oxlib.notify then
			oxlib.notify({ description = tostring(msg), type = ntype })
		-- QBCore toast fallback
		elseif pcall(function() return exports['qb-core'] ~= nil end) then
			local ok, qb = pcall(function() return exports['qb-core']:GetCoreObject() end)
			if ok and qb and qb.Functions and qb.Functions.Notify then
				qb.Functions.Notify(tostring(msg), ntype)
				return
			end
		else
			-- Best-effort ESX fallback without relying on a global
			local ok, esx = pcall(function() return exports['es_extended']:getSharedObject() end)
			if ok and esx and esx.ShowNotification then
				esx.ShowNotification(tostring(msg))
			else
				print('[ic3d_nitro] '..tostring(msg))
			end
		end
	end
end

-- Lightweight logger that respects Config.debug.debugPrints
local function mkLogger(prefix)
	prefix = prefix or 'ic3d_nitro'
	return function(...)
		local cfg = rawget(_G, 'Config')
		local enabled = (cfg and cfg.debug and cfg.debug.debugPrints) or false
		if not enabled then return end
		local args = { ... }
		for i,v in ipairs(args) do args[i] = tostring(v) end
		print(('['..prefix..'] '):gsub('%%','%%%%')..table.concat(args, ' '))
	end
end

Config.DebugPrint = mkLogger('ic3d_nitro')

Last updated

Was this helpful?