CES_TintMeter

#CES_TintMeter

A fully standalone window tint meter for FiveM. Walk up to a vehicle, pull out a handheld meter, press ON, and get a real reading: which window you scanned, the light-transmission percentage, and a PASS / FAIL against your server's legal limit. No ESX, QBCore, or database required.

#Features

  • Standalone – no framework, no database.
  • PASS / FAIL legal limits – separate front and rear limits, set in config.lua.
  • Front vs rear windows – stand at the front of the car to read the front windows, at the back for the rear.
  • Police-only option – restrict the meter with an ACE permission, or leave it open to everyone.
  • Handheld prop – the player holds the meter the whole time it's open.
  • Custom per-vehicle tints – /settint 28 gives a car an exact percentage that every player's meter reads. Can be remembered by plate across restarts (no database).
  • Integration hooks – exports and events for ticket, MDT, and tint-shop scripts.
  • Command + keybind – /tm by default, with an optional rebindable key.
  • Smart targeting – picks the closest vehicle in front of you, including police and occupied vehicles.

#Installation

  1. Drop the CES_TintMeter folder into your resources directory.
  2. Add ensure CES_TintMeter to server.cfg.
  3. (Optional) Set up permissions, see below.
  4. Restart the server.

#How to use

  1. Stand within 5 m of a vehicle, on foot, facing it. Stand near the front to scan the front windows, near the back for the rear windows.
  2. Type /tm (or press your keybind).
  3. Click the red ON button, or press E / Enter / Space.
  4. The screen shows SCANNING, then the window, the percentage, and PASS/FAIL.
  5. The meter closes itself after a few seconds, or press ESC.

#Permissions (ACE)

Out of the box, anyone can use /tm, and only players with tintmeter.settint can use /settint.

Make the meter police-only: set Config.RequireAcePermission = true, then in server.cfg:

add_ace group.police tintmeter.use allow
add_principal identifier.license:YOUR_LICENSE group.police

Let staff set custom tints:

add_ace group.admin tintmeter.settint allow

To let anyone use /settint (for testing), set both Config.RequireAcePermission = false and Config.SetTintRequiresAce = false.

#Custom tints

Command What it does
/settint 28 Sets front and rear to 28% on the vehicle you're in or facing
/settint 70 20 Front 70%, rear 20%
/cleartint Removes the custom tint, back to the GTA tint reading

With Config.CustomTints.persistByPlate = true, custom tints are saved by plate (FiveM's built-in resource storage, no database), so they survive the car being stored, respawned, or the server restarting.

#Default tint readings

GTA tint Front Rear
None 100% 100%
Stock 80% 80%
Green 70% 70%
Light Smoke 35% 35%
Dark Smoke 20% 20%
Limo 15% 15%
Pure Black 5% 5%

Default legal limits: front 70%, rear 35%. A reading below the limit fails. Change both in config.lua.

#Config reference

Setting Default What it does
Config.Command 'tm' Chat command name
Config.Keybind '' Default key (e.g. 'F9'); empty = command only
Config.RequireAcePermission false true = only players with tintmeter.use can scan
Config.AcePermission 'tintmeter.use' ACE needed to scan
Config.SetTintAcePermission 'tintmeter.settint' ACE needed for /settint and /cleartint
Config.SetTintRequiresAce true false + RequireAcePermission = false = anyone can set tints
Config.ScanDistance 5.0 Max distance to the vehicle (metres)
Config.FacingAngle 45.0 How directly you must face the vehicle (degrees)
Config.PullOutTime 1200 Time to raise the meter before the screen appears (ms)
Config.ScanTime 2000 How long "SCANNING" shows (ms)
Config.ResultTime 5000 How long the result stays (ms); 0 = stay open, allow re-scans
Config.Prop phone-style prop Handheld prop model, hand bone, offsets, animation; enabled = false to turn off
Config.LegalLimit front 70, rear 35 PASS/FAIL limits; enabled = false shows the tint name instead
Config.UI.position 'bottom-right' center, bottom-right, bottom-left, top-right, top-left
Config.UI.size 320 Meter size in pixels
Config.Tints see table Name and front/rear % for each GTA tint index
Config.CustomTints enabled Command names and plate persistence for custom tints

#For developers: exports & events

Client

-- Open the meter (e.g. from an inventory item)
exports.CES_TintMeter:UseMeter()

-- Last reading this player took (table or nil)
local r = exports.CES_TintMeter:GetLastReading()

-- Fires after every successful scan
AddEventHandler('ces_tintmeter:client:scanned', function(reading) end)

Server

-- Fires after every successful scan (use it to create a ticket / MDT entry)
AddEventHandler('ces_tintmeter:scanned', function(src, reading)
    if reading.legal == false then
        print(('%s: %s %s window %d%% (limit %d%%)'):format(
            reading.officer, reading.plate, reading.window, reading.percent, reading.limit))
    end
end)

exports.CES_TintMeter:GetLastReading(src)              -- last reading by that player
exports.CES_TintMeter:GetCustomTint(plate)             -- { front, rear } or nil
exports.CES_TintMeter:SetCustomTint(vehicle, 30, 20)   -- for tint-shop scripts; front = nil clears

Reading table: plate, model, window ('FRONT'/'REAR'), percent, tintName, custom (bool), legal (bool, or nil if limits are off), limit, coords, time (unix), officer (player name).

#Troubleshooting

  • "You are not authorised to use the tint meter." Config.RequireAcePermission is true and you don't have tintmeter.use. Add the ACE lines above, or set it to false.
  • "/settint says I don't have permission." Grant tintmeter.settint, or turn off both permission settings for testing.
  • The prop sits oddly in the hand. Tweak Config.Prop.offset / rotation, or swap model for another small prop.
  • Custom tint isn't remembered after the car respawns. Make sure Config.CustomTints.persistByPlate = true, and that the car keeps the same plate.

#Support

Still stuck? Join our Discord: DISCORD INVITE LINK

#Credits

  • LCD font: DSEG by keshikan, SIL Open Font License 1.1 (see html/fonts/DSEG-LICENSE.txt).

Created by Crazy Eyes Studio (CES)

No ratings yet