Tommy's Scripts
  • Information
    • FiveM Escrow System
  • Paid Scripts
    • Tommy's ELS
    • Tommy's Radar Detector
    • Tommy's POV
    • Tommy's Radio
    • Tommy's HUD (Legacy V1)
    • Custom Unit Number
    • GTA:O Loading Screen
  • Free Scripts
    • Tommy's Lights Sync
    • Tommy's Discord API
    • Priority Status
Powered by GitBook
On this page
  • Configuration
  • Ox Inventory Mod (Optional)
  • Known Issues w/ 3rd Party Chats
  1. Paid Scripts

Tommy's ELS

Configuration guide, common issues & solutions, code snippets, and more.

Last updated 9 months ago

|

Escrow Encrypted: Yes

Requirements: None

Features

  • Highly Configurable

  • Up to six siren tones (can be server sided as well)

  • Pattern Sync between vehicles (enabled with config)

  • Speed based patterns (enabled with config) (Faster you go the faster your lights flash)

  • Highly optimized (relative to other popular ELS scripts) (I’m activley working on more optimizations)

  • New Environmental Light System (Can be completely edited in the configuration) (Only draws one light per car, and colors the light by choosing the most prominent color out of the currently activated lights.)

  • Repairing the vehicle or spawning a car will not have extras pop up everywhere.

  • Responsive & Modern UI

Configuration

patternSpeed

  • Time in milliseconds between each pattern change. Lower values result in faster pattern changes.

speedAdjustFactor

  • Determines how much the vehicle's speed affects the pattern speed. Set to 0.0 to disable speed adjustment.

sirenParkKill

  • Specifies whether the sirens should be disabled when the driver exits the vehicle. Set to true to enable this feature.

hornInterrupt

  • Specifies whether the use of the horn should interrupt the siren. Set to true to enable this feature.

defaultKeybinds

  • Default keybinds for various actions. Replace the values with the desired keybinds. Set to "NONE" to disable a specific action.

vehicles

  • List of vehicles enabled for ELS. Each vehicle in the array should have the following properties:

    • name: The model name of the vehicle.

    • patternSet: The pattern set to use for this vehicle.

    • stages: Configuration for each stage of lighting. The stages object should include the following properties:

      • stageOneExtras: An array of extras used for stage one lighting.

      • stageTwoExtras: An array of extras used for stage two lighting.

      • stageThreeExtras: An array of extras used for stage three lighting.

      • takeDownExtras: An array of extras used for take down lights.

patternSync

  • Determines whether the patterns should be synchronized across all vehicles.

patterns

  • List of available patterns. Each pattern includes the following properties:

    • name: The name of the pattern set.

    • uiExtras: Extra numbers used for UI graphics.

    • Extras for each stage, numbered from 1 to 14. Each extra is represented by a string of 0s and 1s indicating its state.

changeStage

  • Defines how the stage lighting is changed based on the stage. Modify this function according to your requirements.

environmentalLightFunction

  • The function responsible for environmental lighting. Leave as is unless you're a developer intending to modify environmental lights' behavior.

Important Notes

  • Ensure that the provided Lua config aligns with your specific needs.

  • The values in the configuration can be adjusted as per your requirements.

config.lua
Config = {}--[[ Tommy's ELS Configuration (Developed by Tommy141x)
  ______                               _          ________   _____
 /_  __/___  ____ ___  ____ ___  __  _( )_____   / ____/ /  / ___/
  / / / __ \/ __ `__ \/ __ `__ \/ / / /// ___/  / __/ / /   \__ \
 / / / /_/ / / / / / / / / / / / /_/ / (__  )  / /___/ /______/ /
/_/  \____/_/ /_/ /_/_/ /_/ /_/\__, / /____/  /_____/_____/____/
                              /____/
[[-- Configuration --]]

-- Time in MS between each pattern change. (lower means faster)
Config.patternSpeed = 60

-- How much should vehicle speed affect the pattern speed (Higher means more)? Set to 0.0 to disable.
Config.speedAdjustFactor = 0.5

-- Should the sirens be disabled when the driver exits the vehicle?
Config.sirenParkKill = true

-- Should use of the horn interrupt the siren?
Config.hornInterrupt = false

-- Default Keybinds (https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/) (Set to "NONE" to disable)
Config.defaultKeybinds = {
    changeStage = "Q",
    sirenTone1 = "1",
    sirenTone2 = "2",
    sirenTone3 = "3",
    sirenTone4 = "4",
    sirenTone5 = "5",
    sirenTone6 = "6",
    advLights = "7",
    wrnLights = "8",
    primLights = "9",
    tkdLights = "0",
    patternDown = "MINUS",
    patternUp = "EQUALS",
}

-- List of vehicles that are ELS enabled (should correspond to the names of the vcf files in the vcf folder).
-- Only extras with IsElsControlled set to true in the vcf file will be controlled by this script.
Config.vehicles = {
    [1] = {
        name = "carOne", -- Model Name of the vehicle
        patternSet = "patternSetOne", -- Pattern Set to use
        stages = { -- Configure what extras are used for each stage, and what extras are used for the take down lights.
            stageOneExtras = { 7, 8, 9 },
            stageTwoExtras = { 5, 6 },
            stageThreeExtras = { 1, 2, 3, 4 },
            takeDownExtras = { 11 },
        }
    },
    [2] = {
        name = "carTwo", -- Model Name of the vehicle
        patternSet = "patternSetOne", -- Pattern Set to use
        stages = { -- Configure what extras are used for each stage, and what extras are used for the take down lights.
            stageOneExtras = { 7, 8, 9 },
            stageTwoExtras = { 5, 6 },
            stageThreeExtras = { 1, 2, 3, 4 },
            takeDownExtras = { 11 },
        }
    },
}

-- Sync patterns across all vehicles.
Config.patternSync = true

-- List of patterns that can be used. (Only extras with IsElsControlled in the VCF file will be used for patterns)
-- You can edit the colors of the UI in the html file.
Config.patterns = {
    [1] = { -- Pattern Set (You can add as many of these as you want and reference them in the vehicles list)
        name = "patternSetOne", -- Pattern Set Name
        [1] = { -- Pattern
            name = "NORMAL", -- Pattern Name
            uiExtras = { prim1 = 1, prim2 = 2, wrn1 = 5, wrn2 = 6, adv1 = 7, adv2 = 8, adv3 = 9 }, -- Extra Numbers Used for UI Graphics
            [1] = "000000111111000000111111000000111111", -- Extra 1
            [2] = "111000111000111000111000111000111000", -- Extra 2
            [3] = "000111000111000111000111000111000111", -- Extra 3
            [4] = "111111000000111111000000111111000000", -- Extra 4
            [5] = "111000111000111000111000111000111000", -- Extra 5
            [6] = "000111000111000111000111000111000111", -- Extra 6
            [7] = "100000110001100000000001100011000001", -- Extra 7
            [8] = "011100000100000111111000001000001110", -- Extra 8
            [9] = "100000110001100000000001100011000001", -- Extra 9
            [10] = "111111000000111111000000111111000000", -- Extra 10
            [11] = "111111000000111111000000111111000000", -- Extra 11
            [12] = "111111000000111111000000111111000000", -- Extra 12
            [13] = "111111000000111111000000111111000000", -- Extra 13
            [14] = "111111000000111111000000111111000000", -- Extra 14
        },
        [2] = { -- Pattern
            name = "LEFT", -- Pattern Name
            uiExtras = { prim1 = 1, prim2 = 2, wrn1 = 5, wrn2 = 6, adv1 = 7, adv2 = 8, adv3 = 9 }, -- Extra Numbers Used for UI Graphics
            [1] = "000000000111111", -- Extra 1
            [2] = "000000111111000", -- Extra 2
            [3] = "000111111000000", -- Extra 3
            [4] = "111111000000000", -- Extra 4
            [5] = "000001111100000", -- Extra 5
            [6] = "111000111000111", -- Extra 6
            [7] = "000000000111111", -- Extra 7
            [8] = "000011111110000", -- Extra 8
            [9] = "111111000000000", -- Extra 9
            [10] = "101101001011010", -- Extra 10
            [11] = "101101001011010", -- Extra 11
            [12] = "101101001011010", -- Extra 12
            [13] = "101101001011010", -- Extra 13
            [14] = "101101001011010", -- Extra 14
        },
        [3] = { -- Pattern
            name = "RIGHT", -- Pattern Name
            uiExtras = { prim1 = 1, prim2 = 2, wrn1 = 5, wrn2 = 6, adv1 = 7, adv2 = 8, adv3 = 9 }, -- Extra Numbers Used for UI Graphics
            [1] = "111111000000000", -- Extra 1
            [2] = "000111111000000", -- Extra 2
            [3] = "000000111111000", -- Extra 3
            [4] = "000000000111111", -- Extra 4
            [5] = "111000111000111", -- Extra 5
            [6] = "000001111100000", -- Extra 6
            [7] = "111111000000000", -- Extra 7
            [8] = "000011111110000", -- Extra 8
            [9] = "000000000111111", -- Extra 9
            [10] = "101101001011010", -- Extra 10
            [11] = "101101001011010", -- Extra 11
            [12] = "101101001011010", -- Extra 12
            [13] = "101101001011010", -- Extra 13
            [14] = "101101001011010", -- Extra 14
        },
        [4] = { -- Pattern
            name = "BURN", -- Pattern Name
            uiExtras = { prim1 = 1, prim2 = 2, wrn1 = 5, wrn2 = 6, adv1 = 7, adv2 = 8, adv3 = 9 }, -- Extra Numbers Used for UI Graphics
            [1] = "11111111111111111", -- Extra 1
            [2] = "11111111111111111", -- Extra 2
            [3] = "11111111111111111", -- Extra 3
            [4] = "11111111111111111", -- Extra 4
            [5] = "11111111111111111", -- Extra 5
            [6] = "11111111111111111", -- Extra 6
            [7] = "11111111111111111", -- Extra 7
            [8] = "11111111111111111", -- Extra 8
            [9] = "11111111111111111", -- Extra 9
            [10] = "11111111111111111", -- Extra 10
            [11] = "11111111111111111", -- Extra 11
            [12] = "11111111111111111", -- Extra 12
            [13] = "11111111111111111", -- Extra 13
            [14] = "11111111111111111", -- Extra 14
        },
    },
}

-- Feel free to configure how the stage lighting is changed based on the stage
-- For example, in the way I currently have it below, stage one lighting is disabled in stages 2 and 3.
Config.changeStage = function(code, car)
    if code == 1 then
        car.stageOne = true
        car.stageTwo = false
        car.stageThree = false
    elseif code == 2 then
        car.stageOne = false
        car.stageTwo = true
        car.stageThree = false
    elseif code == 3 then
        car.stageOne = false
        car.stageTwo = true
        car.stageThree = true
    else
        car.stageOne = false
        car.stageTwo = false
        car.stageThree = false
    end
end

-- The environmental light function, you don't need to edit this unless your a developer looking to change the way environmental lights work with this script.
Config.environmentalLightFunction = function(elsVehicle, netID)
    if elsVehicle.stageOne or elsVehicle.stageTwo or elsVehicle.stageThree then
        -- Loop through all vehicles
        local toDraw = {}
        local r = 0
        local g = 0
        local b = 0
        for extra, color in pairs(elsVehicle.extraColors) do
            -- Get all extras and colors from VCF File
            if NetworkDoesNetworkIdExist(netID) and IsVehicleExtraTurnedOn(NetworkGetEntityFromNetworkId(netID), extra) then
                table.insert(toDraw, color) -- If the extra is turned on then add the color to the table to draw
            end
        end
        -- Loop through all colors to find the one with the most occurences.
        -- I did this so that if you have 2 red and 1 blue, it will draw red.
        -- I personally don't like drawing both red and blue at the same time because it looks funky.
        -- Also only drawing one color / one light at a time is better for performance.
        for k, v in pairs(toDraw) do
            local redOccurences = 0
            if v == "red" then
                -- "red" is whats found in the VCF File
                redOccurences = redOccurences + 1
            end
            local blueOccurences = 0
            if v == "blue" then
                -- "blue" is whats found in the VCF File
                blueOccurences = blueOccurences + 1
            end
            local amberOccurences = 0
            if v == "amber" then
                -- "amber" is whats found in the VCF File
                amberOccurences = amberOccurences + 1
            end
            local whiteOccurences = 0
            if v == "white" then
                -- "amber" is whats found in the VCF File
                whiteOccurences = whiteOccurences + 1
            end
            -- If theres mostly red, draw red.
            if redOccurences > blueOccurences and redOccurences > amberOccurences and redOccurences > whiteOccurences then
                r = 255
                g = 0
                b = 0
                -- If theres mostly blue, draw blue.
            elseif blueOccurences > redOccurences and blueOccurences > amberOccurences and blueOccurences > whiteOccurences then
                r = 0
                g = 0
                b = 255
                -- If theres mostly amber, draw amber.
            elseif amberOccurences > redOccurences and amberOccurences > blueOccurences and amberOccurences > whiteOccurences then
                r = 255
                g = 165
                b = 0
                -- Otherwise draw a random mix between red and blue.
            elseif whiteOccurences > redOccurences and whiteOccurences > blueOccurences and whiteOccurences > amberOccurences then
                r = 255
                g = 255
                b = 255
            else
                r = math.random(0, 255)
                g = 0
                b = math.random(0, 255)
            end
        end
        -- Now that our rgb is picked out for this environmental light, let's draw it!
        if NetworkDoesNetworkIdExist(netID) then
            local coords = GetEntityCoords(NetworkGetEntityFromNetworkId(netID))
            -- DrawLightWithRange(x, y, z, r, g, b, range, intensity)
            DrawLightWithRange(coords.x, coords.y, coords.z, r, g, b, 15.0, 0.5) -- The 0.5 is the brightness of the environmental lights.
        end
    end
end

ELS In-Game UI

The ELS in-game UI allows for customization of the UI files without encryption. You have the freedom to make any desired changes. Additionally, the display of extras on the UI can be configured per pattern set.

Server Sided Sirens

Example VCF File:

<?xml version="1.0" encoding="utf-8"?>
<!-- ELS VEHICLE CONFIGURATION FILE -->
<vcfroot Description="Example VCF File" Author="Tommy141x" >
  <!-- INTERFACE (UNUSED BY THIS SCRIPT) -->
  <INTERFACE>
  	<LstgActivationType>manual</LstgActivationType>
  	<DefaultSirenMode>standby</DefaultSirenMode>
  	<InfoPanelHeaderColor>grey</InfoPanelHeaderColor>
  	<InfoPanelButtonLightColor>orange</InfoPanelButtonLightColor>
  </INTERFACE>
  <!-- EXTRAS OVERRIDE AND ENV LIGHTING (IsElsControlled and Color are used by this script) -->
  <EOVERRIDE>	
  	<Extra01 IsElsControlled="true" AllowEnvLight="true" Color="red" OffsetX="-0.70" OffsetY="-0.20" OffsetZ="0.50" />
  	<Extra02 IsElsControlled="true" AllowEnvLight="true" Color="red" OffsetX="-0.25" OffsetY="-0.20" OffsetZ="0.50" />
  	<Extra03 IsElsControlled="true" AllowEnvLight="true" Color="blue" OffsetX="0.25" OffsetY="-0.20" OffsetZ="0.50" />
  	<Extra04 IsElsControlled="true" AllowEnvLight="true" Color="blue" OffsetX="0.70" OffsetY="-0.20" OffsetZ="0.50" />
  	<Extra05 IsElsControlled="true" AllowEnvLight="true" Color="red" OffsetX="-0.70" OffsetY="-0.20" OffsetZ="0.50" />
  	<Extra06 IsElsControlled="true" AllowEnvLight="true" Color="blue" OffsetX="0.70" OffsetY="-0.20" OffsetZ="0.50" />
  	<Extra07 IsElsControlled="true" AllowEnvLight="true" Color="amber" OffsetX="-0.40" OffsetY="-0.80" OffsetZ="0.40" />
  	<Extra08 IsElsControlled="true" AllowEnvLight="true" Color="amber" OffsetX="0.00" OffsetY="-0.80" OffsetZ="0.40" />
  	<Extra09 IsElsControlled="true" AllowEnvLight="true" Color="amber" OffsetX="0.40" OffsetY="-0.80" OffsetZ="0.40" />
  	<Extra10 IsElsControlled="true" />
  	<Extra11 IsElsControlled="true" />
  	<Extra12 IsElsControlled="false" />
  </EOVERRIDE>
  <!-- MISC (UNUSED BY THIS SCRIPT)-->
  <MISC>
  	<VehicleIsSlicktop>false</VehicleIsSlicktop>
  	<ArrowboardType>off</ArrowboardType>
  	<UseSteadyBurnLights>true</UseSteadyBurnLights>
  	<DfltSirenLtsActivateAtLstg>3</DfltSirenLtsActivateAtLstg>
  	<Takedowns AllowUse="true" Mirrored="true" />
  	<SceneLights AllowUse="true" IlluminateSidesOnly="true" />	
  </MISC>
  <!-- CRUISE (UNUSED BY THIS SCRIPT)-->
  <CRUISE>
  	<DisableAtLstg3>true</DisableAtLstg3>
  	<UseExtras Extra1="true" Extra2="false" Extra3="false" Extra4="true" />
  </CRUISE>
  <!-- AUX CORONAS (UNUSED BY THIS SCRIPT) -->
  <ACORONAS>
  	<Headlights DfltPattern="1" ColorL="white" ColorR="white" />
  	<TailLights DfltPattern="0" ColorL="red" ColorR="red" />
  	<IndicatorsF DfltPattern="0" ColorL="white" ColorR="white" />
  	<IndicatorsB DfltPattern="0" ColorL="red" ColorR="red" />
  	<ReverseLights DfltPattern="0" ColorL="white" ColorR="white" />
  </ACORONAS>
  <!-- SOUNDS (Horn Interrupt is in the configuration, below is an example of a stock gta siren and a server sided siren.)-->
  <SOUNDS>
  	<MainHorn InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCSO_NEW_HORN" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcso_new" SoundSet="OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET" />
  	<SrnTone1 InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCFD_NEW_SIREN_ADAM" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcfd_new" SoundSet="OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET" />
  	<SrnTone2 InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCFD_NEW_SIREN_BOY" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcfd_new" SoundSet="OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET" />
  	<SrnTone3 InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCFD_NEW_SIREN_CHARLES" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcfd_new" SoundSet="OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET" />
  	<SrnTone4 InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCSO_NEW_SIREN_ADAM" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcso_new" SoundSet="OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET" />
  	<SrnTone5 InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCSO_NEW_SIREN_BOY" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcso_new" SoundSet="OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET" />
  	<SrnTone6 InterruptsSiren="true" AudioString="OISS_SSA_VEHAUD_BCSO_NEW_SIREN_CHARLES" SoundBank="dlc_serversideaudio/oiss_ssa_vehaud_bcso_new" SoundSet="OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET" />
  </SOUNDS>
  <!-- WRNL (UNUSED BY THIS SCRIPT)-->
  <WRNL LightingFormat="leds" >
  	<PresetPatterns>
  		<Lstg3 Enabled="true" Pattern="26" />
  	</PresetPatterns>
  	<ForcedPatterns>
  		<MainHorn Enabled="false" Pattern="0" />
  		<SrnTone1 Enabled="false" Pattern="0" />
  		<SrnTone2 Enabled="false" Pattern="0" />
  		<SrnTone3 Enabled="false" Pattern="0" />
  		<SrnTone4 Enabled="false" Pattern="0" />
  		<PanicMde Enabled="false" Pattern="0" />
  		<OutOfVeh Enabled="false" Pattern="0" />
  	</ForcedPatterns>
  	<ScanPatternCustomPool Enabled="false" Sequential="true" >
  		<Pattern>0</Pattern>
  		<Pattern>0</Pattern>
  		<Pattern>0</Pattern>
  	</ScanPatternCustomPool>
  </WRNL>
  <!-- PRML (UNUSED BY SCRIPT) -->
  <PRML LightingFormat="leds" ExtrasActiveAtLstg2="1and4" >
  	<PresetPatterns>
  		<Lstg2 Enabled="true" Pattern="140" />
  		<Lstg3 Enabled="true" Pattern="123" />
  	</PresetPatterns>
  	<ForcedPatterns>
  		<MainHorn Enabled="false" Pattern="0" />
  		<SrnTone1 Enabled="false" Pattern="0" />
  		<SrnTone2 Enabled="false" Pattern="0" />
  		<SrnTone3 Enabled="false" Pattern="0" />
  		<SrnTone4 Enabled="false" Pattern="0" />
  		<PanicMde Enabled="false" Pattern="0" />
  		<OutOfVeh Enabled="false" Pattern="0" />
  	</ForcedPatterns>
  	<ScanPatternCustomPool Enabled="false" Sequential="true">
  		<Pattern>0</Pattern>
  		<Pattern>0</Pattern>
  		<Pattern>0</Pattern>
  	</ScanPatternCustomPool>
  </PRML>
  <!-- SECL (UNUSED BY SCRIPT) -->
  <SECL LightingFormat="traf" DisableAtLstg3="false" >
  	<PresetPatterns>
  		<Lstg1 Enabled="true" Pattern="2" />
  		<Lstg2 Enabled="true" Pattern="2" />
  		<Lstg3 Enabled="true" Pattern="2" />
  	</PresetPatterns>
  	<ForcedPatterns>
  		<MainHorn Enabled="false" Pattern="0" />
  		<SrnTone1 Enabled="false" Pattern="0" />
  		<SrnTone2 Enabled="false" Pattern="0" />
  		<SrnTone3 Enabled="false" Pattern="0" />
  		<SrnTone4 Enabled="false" Pattern="0" />
  		<PanicMde Enabled="false" Pattern="0" />
  		<OutOfVeh Enabled="false" Pattern="0" />
  	</ForcedPatterns>
  	<ScanPatternCustomPool Enabled="false" Sequential="true" >
  		<Pattern>0</Pattern>
  		<Pattern>0</Pattern>
  		<Pattern>0</Pattern>
  	</ScanPatternCustomPool>
  </SECL>
</vcfroot>

Resmon Usage: With 6 active vehicles in close proximity, achieving a resmon value of 0.62 is considered optimal. Ongoing optimizations and bug fixes are being implemented to further improve performance.

Known Bugs

  • Occasionally, after a few hours of roleplay, AI cars with ELS may toggle extras and environmental lighting unexpectedly, resulting in visually amusing situations.

  • Rarely, vehicles may have a ghost stock GTA siren while in Code 3 mode.

To-Do

  • Optimize RPC events for improved performance.

  • Add NetID checks for optimization and provide warnings in the console.

  • Tutorial Video: A tutorial video demonstrating the setup and configuration of Tommy's ELS is planned for future release.

Ox Inventory Mod (Optional)

If you wish to deactivate the hotbar shortcuts while in an emergency vehicle, modify the client.lua file on line 732.

Replace this:

if invOpen or IsNuiFocused() or not invHotkeys then return end

With this:

if invOpen or IsNuiFocused() or (GetVehicleClass(GetVehiclePedIsIn(GetPlayerPed(-1), false)) == 18) or not invHotkeys then return end

Known Issues w/ 3rd Party Chats

Unknown/Invalid Command ELS in Chat (ESX Solution)

For ESX users, go into es_extended/server/main.lua and find lines 324-331. Replace this:

AddEventHandler('chatMessage', function(playerId, author, message)
  local xPlayer = ESX.GetPlayerFromId(playerId)
  if message:sub(1, 1) == '/' and playerId > 0 then
    CancelEvent()
    local commandName = message:sub(1):gmatch("%w+")()
    xPlayer.showNotification(TranslateCap('commanderror_invalidcommand', commandName))
  end
end)

With this:

AddEventHandler('chatMessage', function(playerId, author, message)
  local xPlayer = ESX.GetPlayerFromId(playerId)
  if message:sub(1, 1) == '/' and (not string.lower(message):find("els", 1, true)) and playerId > 0 then
    CancelEvent()
    local commandName = message:sub(1):gmatch("%w+")()
    xPlayer.showNotification(TranslateCap('commanderror_invalidcommand', commandName))
  end
end)

Command Repeated in Chat (Standalone Solution)

https://github.com/FAXES/fax-hidecmds/blob/master/server.lua
AddEventHandler('chatMessage', function(Source, Name, Msg)
    args = stringsplit(Msg, " ")
    CancelEvent()
    if string.find(args[1], "/") then
        local cmd = args[1]
        table.remove(args, 1)
	else
		TriggerClientEvent('chatMessage', -1, Name, { 255, 255, 255 }, Msg)
	end
end)

function stringsplit(inputstr, sep)
    if sep == nil then
        sep = "%s"
    end
    local t={} ; i=1
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
        t[i] = str
        i = i + 1
    end
    return t
end

Please note: This documentation serves as a guide to understand and configure Tommy's ELS script effectively

Tommy's ELS provides an easy way to configure different sirens for various vehicles and enables server-sided sirens. An example VCF file configuration is provided below, utilizing server-sided sirens from .

We use a new FiveM Native called , which is a more optimized way to detect key presses, this native calls a command when a key is pressed, and the way that it calls this command has caused some issues with outdated resources.

For users seeing a /~els_ command in chat when using the keybinds, this means you do not have a chat script which hides chat messages that are commands. You can add this functionality with a script such as , or you can implement it yourself by adding the below snippet to any server-side lua file:

Kwoks's free SAS script
RegisterKeyMapping
HideCMDs by FAXES
FiveM Post
Store Page
Page cover image