# Welcome to Luxart Engineering

Free law enforcement resources for FiveM.

## Luxart Vehicle Control: <mark style="color:orange;">Fleet</mark>

The new an improved latest resource from Luxart Engineering, **coming soon**!

<div align="left"><figure><img src="/files/MvCwwiYb3JIq39olt5QF" alt=""><figcaption><p>LVC:F Logo</p></figcaption></figure></div>

{% content-ref url="/pages/EvDrceYhByCu6uIo2r8i" %}
[What is LVC:Fleet?](/fleet/readme-1)
{% endcontent-ref %}

{% content-ref url="/pages/9LSvyoXaSS02ud7vdm3g" %}
[Resource Installation](/fleet/resource-installation)
{% endcontent-ref %}

{% embed url="<https://github.com/TrevorBarns/luxart-vehicle-control-fleet/releases>" %}

## Luxart Vehicle Control <mark style="color:red;">v3</mark>

The O.G. modified emergency light and siren controller for FiveM.

<div align="left"><figure><img src="/files/9FZnQmRbGugyOnkf3b7F" alt=""><figcaption><p>LVC v3 Logo</p></figcaption></figure></div>

{% embed url="<https://forum.cfx.re/t/luxart-vehicle-control-v3/4436673/1>" %}

{% content-ref url="/pages/ejzQRilVSblQ7uwP5nnA" %}
[Resource Installation](/v3/resource-installation)
{% endcontent-ref %}

{% embed url="<https://github.com/TrevorBarns/luxart-vehicle-control/releases>" %}

## Luxart Pro Laser 4

LiDAR / Radar gun resource for FiveM.

<div align="left"><figure><img src="/files/eDBm76JdLSyuQt9HaXzE" alt=""><figcaption></figcaption></figure></div>

{% content-ref url="/pages/CNtaCAVKYbIAv75R6ova" %}
[Resource Installation](/pro-laser-4/resource-installation)
{% endcontent-ref %}

{% embed url="<https://github.com/TrevorBarns/ProLaser4/releases>" %}


# Product Roadmaps

Luxart Engineering Product Roadmaps

{% embed url="<https://trello.com/b/j3KM2fmu/luxart-engineering>" %}
Luxart Engineering Trello
{% endembed %}

### <mark style="color:orange;">Fleet</mark>

* [x] ~~**Storage Management:** save & load configurations~~
* [x] ~~**Expand Rumbler / Howler Control:** client menu control, VCF settings.~~
* [x] ~~**Guaranteed Plugin Compatibility:** test and verify plug-ins work without issue.~~
* [ ] **VCF Examples & Packs:** premade LVC:F ready packs.
* [ ] **Copy Profile**[**:**](https://docs.luxartengineering.com/fleet/what-is-lvc-fleet) ability to copy configuration from one profile to another.
* [ ] **VCF XML Generator GUI:** create VCFs quickly through the help of a user interface.
* [ ] **Dynamic HUD Elements:** additional HUD buttons for plugin integration.
* [ ] **Passenger Control:** allow passengers of vehicle to use siren controller.

### <mark style="color:red;">v3</mark>

* [ ] **Dynamic HUD Elements:** additional HUD buttons for plugin integration.
* [ ] **Passenger Control:** allow passengers of vehicle to use siren controller.

### Shared Plugins

TBA.

### Pro Laser 4

* [x] ~~**Controller Support:** use correct controls depending on if the player is in a vehicle or on foot.~~&#x20;
* [x] ~~**Resize & Move OSD:** ability to modify on screen display parameters.~~&#x20;
* [x] ~~**Discord Hook:** allow users to upload records to discord instead of Imgur.~~
* [x] ~~**Improve Cosine Error:** improve accuracy of cosine error, including vertical separation.~~
* [x] ~~**Improve Redundancy:** add crash detection and recovery command.~~
* [ ] **Record Tablet Delay:** reduce upload delay experiment with more frequent uploads.
* [ ] **Bypass Self-Test:** player option to bypass self-test, legal challenge opportunity.
* [ ] **Display Self-Test Timestamp:** ability to view timestamp for ticketing purposes without tablet.
* [ ] **Passenger FPS Angle Support:** dynamic angle limitations in FPS based on seat / vehicle.
* [ ] **Tablet Improvements:** designated area exports and tablet prop.


# Frameworks & Exports

Supported frameworks and exports.

### Frameworks

The below frameworks are supported, please report any conflicts by creating an issue on the respective product or on [my discord](https://discord.link/lvc).

{% hint style="success" %}
QBCore: so long as you do not have have [qb-extras](https://github.com/MrEvilGamer/qb-extras/) installed.
{% endhint %}

{% hint style="success" %}
ESX
{% endhint %}

### Exports&#x20;

**Vehicle State Change Event** (*Coming v3.2.10)*\
Broadcasts event when LVC vehicle state changes. Returns a table/array of data below:<br>

<table data-view="cards"><thead><tr><th>Table Index/Key</th><th>Description</th><th>Options</th></tr></thead><tbody><tr><td><code>state_indic</code></td><td>Indicator/turn-signal state.</td><td><p><code>0</code>: off</p><p><code>1</code>: left on</p><p><code>2</code>: right on,</p><p><code>3</code>: hazard/4-ways on</p></td></tr><tr><td><code>actv_manu</code></td><td>Is manual siren on?</td><td><code>true</code>, <code>false</code></td></tr><tr><td><code>actv_horn</code></td><td>Is the horn on?</td><td><code>true</code>, <code>false</code></td></tr><tr><td><code>state_lxsiren</code></td><td>Main siren tone ID.</td><td><p><code>0</code>: off,</p><p><code>>0</code>: tone ID of main siren </p></td></tr><tr><td><code>state_pwrcall</code></td><td>Powercall/auxiliary siren tone ID.</td><td><p><code>0</code>: off</p><p><code>>0</code>: tone ID of aux/powercall </p></td></tr><tr><td><code>state_airmanu</code></td><td>Airhorn/manual siren tone ID.</td><td><p><code>0</code>: off</p><p><code>>0</code>: tone ID of AirManu</p></td></tr></tbody></table>

{% code title="Example Event Handler" %}

```lua
RegisterNetEvent('lvc:UpdateThirdParty')
AddEventHandler('lvc:UpdateThirdParty', function(update_data)
    local siren_tone = update_data['state_lxsiren'] 
    if siren_tone > 0 then
        --Sirens on, do something...
    end
end)
```

{% endcode %}


# What is LVC:Fleet?

### Introduction

Luxart Vehicle Control: Fleet is a new separate resource based off of the innovations of [Luxart Vehicle Control v3](https://github.com/TrevorBarns/luxart-vehicle-control/). It introduces more finite control of vehicle profiles by the use of Vehicle Configuration Files, abbreviated VCFs. A vehicle configuration's settings are called **profiles** for LVC and describe all the settings encompassed in the VCF. Vehicles, by use of it's game name, are then assigned approved **profiles.**&#x20;

#### **LVC:Fleet specific features over LVCv3:**

* additional profile specific settings (siren defaults, audio settings, menu permissions, etc.)
* on the fly profile selection through LVC menu
* server sided siren integration with **local override** and **peer override**
* rumbler / howler support *(requires installation of compatible siren)*

{% hint style="info" %}
**Local Override**: When active, LVC uses resident.rpf client side sirens instead of any server sided sirens.

**Peer Override:** When active, LVC uses the clients local siren selection for peers of the same *faction. See more in VCF configuration.*
{% endhint %}

#### Basics behind LVC:Fleet:

<figure><img src="/files/0knJjGZfHbSyx9CBDjs3" alt=""><figcaption><p>LVC:F Relationship Diagram</p></figcaption></figure>

In the above diagram, you can see that LSPD, BCSO, SASP all have approved profiles 1, 2, 3. **This allows the player to select from these three profiles in the LVC:Fleet menu**. Meanwhile, the firetruck and ambulance are assigned individual profiles and will not be able to change profiles.

### Features

* Custom server/client side siren assignments
* Ability to change which siren is used through in game menu
* Rumbler / Howler support
* Choice to override other players sirens
* Choice to use client side sirens
* [Menu permissions](/fleet/resource-installation/customize-vcfs#menu-element-permissions)
* In-game siren controller HUD
* Additional functionality through [plugins](/shared-plugins/introduction-to-plugins)
* On-demand siren tone selection through registered keys
* Save / Load user preferences


# Resource Installation

Instructions on how to install LVC:Fleet into your server

#### Download the latest stable release `Luxart.Vehicle.Control.Fleet.vX.X.X.zip` (not source code) from [releases](https://github.com/TrevorBarns/luxart-vehicle-control-fleet/releases).

1. **Copy `RageUI` folder from 'dependencies' folder in resources folder.**

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><em>LVC utilizes a modified release of RageUI, please install it even if you already have another version installed.</em></p></div>
2. **Copy `lvc_fleet` folder to resources folder.**

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><em>Make sure your resource is named <code>lvc_fleet</code> it is required.</em></p></div>
3. **Add `ensure lvc_fleet` to server.cfg.**
4. **(*****Optional*****) Install any desired plugins from plugins folder to `lvc_fleet/PLUGINS/` (*****see*** [***shared plugins***](/shared-plugins/introduction-to-plugins)**)**

{% hint style="info" %}
This resource utilizes [globbing](https://docs.fivem.net/docs/scripting-reference/resource-manifest/resource-manifest/#globbing) which may not be supported in some linux environments. Most releases include `fxmanifest.for.Linux.Servers.no.globbing.zip` which contain a compatible fxmainfest.lua without globbing.
{% endhint %}


# Customize VCFs

VCFs contain LVC:Fleet setting for each profile. Customize them to your desire.

{% hint style="info" %}
VCF files use XML file format and must be valid for LVC:Fleet to load them. Parsing errors will be printed to server console on resource start. You can use [xmlvalidation](https://www.xmlvalidation.com/) to check your VCF file for errors.
{% endhint %}

VCF files should be placed in `/VCF/` folder see [Assign Profiles](/fleet/resource-installation/configure-base-settings#assign-profiles) on how to assign them to specific vehicles.

#### VCFROOT Attributes

```xml
<vcfroot Faction="LEO", Author="TrevorBarns">
```

{% tabs %}
{% tab title="Faction" %}
Determines if two clients profiles are compatible for peer override. <br>

*Example*: setting all profiles used for police departments to "LEO" would allow one agency to use peer override another agencies sirens. This is what prevents fire sirens from being overridden.
{% endtab %}

{% tab title="Author" %}
*Reserved for future implementation.*
{% endtab %}
{% endtabs %}

#### :loud\_sound:HORNS/SIRENS Elements

`<HORNS>` and `<SIRENS>` are containers that can contain multiple HORN and SIREN elements respectively.

{% code title="\<HORN or \<SIREN " %}

```lua
Name="AIRHORN"
Option="1"
ResidentString="SIRENS_AIRHORN"
String="OISS_SSA_VEHAUD_ETC_ADAM"
Ref="OISS_SSA_VEHAUD_ETC_SOUNDSET"
Bank="DLC_SERVERSIDEAUDIO\OISS_SSA_VEHAUD_ETC"
RumblerString="OISS_SSA_VEHAUD_ETC_ADAM"
RumblerRef="OISS_SSA_VEHAUD_ETC_SOUNDSET"
RumblerBank="DLC_SERVERSIDEAUDIO\OISS_SSA_VEHAUD_ETC"
```

{% endcode %}

<table><thead><tr><th width="159">Item Name</th><th>Use</th></tr></thead><tbody><tr><td>ResidentString</td><td>GTA V tone string that references RESIDENT.rpf file.</td></tr><tr><td>String</td><td>Tone string that references server sided sirens. <em>(optional)</em></td></tr><tr><td>Ref</td><td>Tone audio bank reference for server sided sirens. <em>(optional)</em></td></tr><tr><td>Bank</td><td>Tone audio bank name that loaded server sided sirens bank. <em>(optional)</em></td></tr><tr><td>RumblerString</td><td>Tone string that references resident or server sided sirens. <em>(optional)</em></td></tr><tr><td>RumblerRef</td><td>Tone string that references resident or server sided sirens. <em>(optional)</em></td></tr><tr><td>RumblerBank</td><td>Tone audio bank name that loaded server sided sirens bank. <em>(optional)</em></td></tr><tr><td>Option</td><td>Determines when this tone can be played: 1-Cycle &#x26; Button, 2-Cycle Only, 3-Button Only, 4-Disabled. <em>(optional)</em></td></tr><tr><td>Fallback</td><td>Determines what siren should be played when using peer override and the other player is using a siren index that is greater than the local players siren count. <em>e.g. playing 4th siren and the local player only has 3 sirens assigned.</em> <em>(Recommended)</em></td></tr></tbody></table>

#### :gear: SIREN\_CONFIG Element

```xml
<SIREN_CONFIG>
	<Horn ToneID="1"/>
	<Primary_Manual ToneID="1"/>
	<Secondary_Manual ToneID="2"/>
	<Auxiliary ToneID="1"/>
	<Airhorn_Intrp Enabled="true"/>
	<Reset_Standby Enabled="true"/>
	<Park_Kill Enabled="true"/>
	<Peer_Override Enabled="false"/>
	<Local_Override Enabled="true"/>
	<Rumbler Enabled="false"/>
</SIREN_CONFIG>
```

<table><thead><tr><th width="178">Item Name</th><th>Use</th></tr></thead><tbody><tr><td>*ToneID</td><td>Which index for respective tones (HORN, PRI. MANU., SEC. MANU.)</td></tr><tr><td>Airhorn_Intrp</td><td>Airhorn interrupt siren on activation, default behavior.</td></tr><tr><td>Reset_Standby</td><td>Siren resets to first index on toggle, default behavior.</td></tr><tr><td>Park_Kill</td><td>Turn siren turn off on vehicle exit, default behavior.</td></tr><tr><td>Local_Override</td><td>Override any server side sirens with client side sirens. <br><strong>(Must be enabled if no server sided sirens are used.)</strong></td></tr><tr><td>Peer_Override</td><td>Override other players siren choice with select profile. <br><em>(Recommend disabled if no server sided sirens are used.)</em></td></tr><tr><td>Rumbler</td><td>Enables rumbler/howler functionality <br><strong>(Requires RumblerString, RumblerRef, RumblerBank to be set.)</strong></td></tr></tbody></table>

#### :traffic\_light: HUD Element

```xml
<HUD Enabled="true" Backlight_Mode="1"/>
```

{% tabs %}
{% tab title="Enabled" %}
Default siren controller HUD display state.&#x20;
{% endtab %}

{% tab title="Backlight Mode" %}
1 = Auto: toggle HUD backlight with headlight state

2 = Always off

3 = Always on
{% endtab %}
{% endtabs %}

#### :sound:Audio Element

```xml
<AUDIO>
	<Radio Enabled="true"/>				
	<Airhorn_SFX Enabled="false"/>
	<Manual_SFX Enabled="false"/>
	<Hazards_SFX Enabled="true"/>
	<Activity_Reminder_Interval_Index Val="1"/>
	<Scheme_Index Val="1"/>
	<SCHEMES>
		<SCHEME String="SSP2000"/>
		<SCHEME String="SSP3000"/>
		<SCHEME String="Cencom"/>
		<SCHEME String="ST300"/>
		<SCHEME String="Code3-MCB"/>
	</SCHEMES>
	<On_Volume Val="0.5"/>
	<Off_Volume Val="0.7"/>
	<Upgrade_Volume Val="0.5"/>
	<Downgrade_Volume Val="0.7"/>
	<Hazards_Volume Val="0.09"/>
	<Lock_Volume Val="0.25"/>
	<Lock_Reminder_Volume Val="0.2"/>
	<Activity_Reminder_Volume Val="0.09"/>
</AUDIO>
```

<table><thead><tr><th width="187">Item Name</th><th>Use</th></tr></thead><tbody><tr><td>Radio</td><td>Radio wheel functionality.</td></tr><tr><td>*_SFX</td><td>Button sound effects. (Hazards, Airhorn, Manual tone)</td></tr><tr><td>Scheme_Index</td><td>Button SFX audio scheme index from <code>&#x3C;SCHEMES></code> element.</td></tr><tr><td>Activity_Reminder_Interval_Index</td><td>Activity reminder settings. 'Off', '1/2', '1', '2', '5', '10' in minutes.</td></tr><tr><td>*_Volume</td><td>SFX volume to be used.</td></tr><tr><td>SCHEME element(s)</td><td><p>Name of approved SFX folder(s) as found in <code>/UI/sounds/</code> </p><p>(See <a href="/pages/gXjpGJaCldFol6V990SF#custom-audio-schemes">Advanced Configuration - Custom Audio Schemes</a>)</p></td></tr></tbody></table>

#### :closed\_lock\_with\_key: Menu Element - Permissions

Each element controls the access to a menu element.

```xml
<MENU>
	<Menu_Access Enabled='true'/>
	<Menu_Main_Siren_Settings Enabled="true"/>
	<Toggle_Peer_Override Enabled="true"/>
	<Toggle_Local_Override Enabled="true"/>
	<Toggle_Airhorn_Intrp Enabled="true"/>
	<Toggle_Reset_Standby Enabled="true"/>
	<Custom_Tone_Options Enabled="true"/>
	<Custom_Manual Enabled="true"/>
	<Custom_Auxiliary Enabled="true"/>
	<Toggle_Park_Kill Enabled="true"/>
	<Menu_HUD_Settings Enabled="true"/>
	<Toggle_HUD Enabled="true"/>
	<Custom_Backlight_Mode Enabled="true"/>
	<Menu_Audio_Settings Enabled="true"/>
	<Toggle_Radio Enabled="true"/>
	<Custom_Scheme Enabled="true"/>
	<Toggle_Clicks Enabled="true"/>
	<Custom_Activity_Reminder Enabled="true"/>
	<Menu_Plugins Enabled="true"/>
</MENU>
```


# Configure Base Settings

## Set a Community&#x20;

This unique set of characters for your community will be used for profile saving.

* The ID should be 4-6 alphanumerical characters.
* Spaces are not allowed and will not work, dashes can be used instead.
* Some examples may be your servers abbreviation, name, etc.
  * **Examples:**\
    `'LCPS'`, `'LCPSR'`, `'SARP'`, `'LSDOJ'`, `'JakesRP'`, etc.

{% hint style="info" %}
The purpose of this string is to differentiate the client side saves between servers. Since it is possible (and likely) that servers may use the same profile names, but different profile siren assignments.
{% endhint %}

{% hint style="warning" %}
This string should be set once, and never changed as it will result in loss of LVC saves for all players. It is not public facing so even if the server name changes it does not need to change.
{% endhint %}

## Configure Controls

#### Register Key Maps

Users may change these in their GTA V > Settings > Hotkeys > FiveM settings. \
More info: [CFX Cookbook - How RegisterKeyMappings Work](<https://cookbook.fivem.net/2020/01/06/using-the-new-console-key-bindings/ >)\
List of Key&#x73;**:** [RegisterKeyMap Supported Keys](https://pastebin.com/u9ewvWWZ)

`open_menu_key`: sets default key for opening LVC:Fleet Menu.\
`lockout_default_key`: sets default key for toggling LVC:Fleet control lock, which disabled all controls.

**Indicator Controls**

These static keys cannot be changed by the end user and support controller keys as well.\
List of Key&#x73;**:** [CFX Game Reference - Controls](https://docs.fivem.net/docs/game-references/controls/)

`hazard_key`*:* when held for `hazard_hold_duration` toggle 4-way flashers.\
`left_signal_key`: toggle left turn signal.\
`right_signal_key`: toggle right turn signal.

## Assign Profiles

{% code title="SETTINGS.lua" %}

```lua
---------------------VCF FILES---------------------
VCF_Files = {
	'DEFAULT.xml',		--1
	'WHELEN-295.xml',	--2
	'WHELEN-CENCOM-G.xml',	--3
	'MASTERCOM-B.xml',	--4
	'FS2000.xml',		--5
	'TMD.xml',		--6
}

VCF_Assignments = {
	['DEFAULT'] = { 1 },
	['LAPD'] = { 1, 3 }
	['<gameName>'] = { 1, 2, 3, 4, 5 }
}
```

{% endcode %}

### VCF\_Files

Table of VCF file names to be loaded on resource start. These should be locate in `/VCF/` directory. VCF Files represent profiles and contain all of LVC:Fleet's settings for that profile.

{% hint style="info" %}
To load newly installed VCF files, run `refresh` then `restart lvc_fleet`.
{% endhint %}

### VCF\_Assignements

In this table you can add additional vehicles for assignment using the vehicles `<gameName>` exactly as found in `vehicles.meta`. **It is case sensitive**.

<details>

<summary>vehicles.meta example:</summary>

```xml
...
<modelName>so2</modelName> <!-- SPAWN NAME -->
<handlingId>so2</handlingId>
<gameName>so2</gameName> <!-- GAME NAME (WHAT LVC:F USES) -->
<vehicleMakeName />
<expressionDictName>null</expressionDictName>
...
```

</details>

On the right side of the key, `{ 1, 2, 3 }`, for example, are the index's of the profiles you would like assigned to this vehicle. In the above example, that would equate to DEFAULT, WHELEN-295, WHELEN-CENCOM-G. Moreover, changing the order of the VCF\_Files, you would change which profiles are assigned.

Both R\* and LVC truncate down to 11 characters. **It is important that the first 11 characters of the vehicle game name are unique.**

* **Example**:\
  If my addon vehicles `<gameName>` is "*2008 Ford CVPI CHP*" and I have another vehicle "*2008 Ford CVPI LSPD*" both of these after truncate equate to "*2008 Ford C*" therefor LVC:Fleet will not be able to differentiate these.&#x20;

{% hint style="danger" %}
**The default or fallback key `['DEFAULT']` in the VCF\_Assignements table should always be present and never removed. Doing so will result in issues.**
{% endhint %}

#### **Wildcards**

Supported Wildcards:

* `#` represents 1 or more digits.

**How it works:**

1. LVC checks for vehicle profile matching game name. *e.g.* `['2008fpiu1']`
2. If not found, attempts wildcard search, meaning wildcards will be used *secondary* to custom profiles. *e.g.* `['2008fpiu#']`
3. If not found, attempts a less specific wildcard search, leading and trailing numbers. *e.g.* `['#fpiu#']`
4. If not found, use default profile. *e.g.* `['DEFAULT']`

*Example*:\
\* `['veh#'] = { ... }` will be used for vehicles with game names `veh1`, `veh2`, ..., `veh9999`, etc. where exact profile not found.


# Advanced Configuration

Debugging and advanced configuration functionality.

### Debug Mode

To temporarily toggle *debug mode* use chat command `/lvcdebug` this resets on resource restart. For persistent debug mode use convar below.

### **Resource Convars (fxmanifest.lua)**

* `beta_checking` enables beta version notifications to server console.
* `experimental` will mute experimental messages for server console.
* `debug_mode` increases console logging for client, prints \<gameName> of vehicle if no profile was found.

{% hint style="info" %}
Toggling these require the `refresh` command to be ran first, then restart the resource for changes to take effect.
{% endhint %}

### Custom HUD

#### Custom Graphics

The in game siren controller display or heads-up-display UI can be modified to your liking, you will need an understanding of HTML, Javascript, and NUI.&#x20;

{% hint style="info" %}
Support is limited in this area.
{% endhint %}

#### Move Default HUD location

All HUD related functions/code is located in the UI folder. The default position of the HUD is set in `UI/html/style.css`.

```css
#sirenbox {
	display: none;
	position: absolute;
	overflow: hidden;
	width: 602px;
	height: 161px;
	left: 0%;
	top: 68%;
	transform-origin: left top;
	transform: scale(0.6);
	background-image: url("../textures/background.png");
}
```

**The relevant attributes are:&#x20;*****left*****,&#x20;*****top*****, and&#x20;*****transform-origin*****.**

* *left* determines how far in percentage of the screen resolution should the HUD be placed from the left edge. If you wanted to right align the HUD you could change this to `right: XX%`, 0% being against the right edge of the display.
* *top* determines how far down from the top the HUD should be placed.
* *transform-origin* attribute determines which way the HUD should expand on size adjustment. For a bottom right aligned HUD you would want the transform-origin to be `right bottom`. This ensures that the HUD does not expand outside of the screen space.

### Custom Audio Schemes

Custom front end sound effects can be added. Create a new folder in `/UI/sounds` with the desired name of your scheme.

{% hint style="warning" %}
Sound scheme names cannot have any spaces in them.
{% endhint %}

Add scheme name to `<SCHEMES>` object in VCF.

### Ace Menu Permissions

{% hint style="info" %}
:date: Future Feature: estimated release 1.0.0-BETA
{% endhint %}

#### Set up VCF for Permission

To do this add an attribute to the associated menu item you would like to limit a profile's VCF.

```xml
<MENU>
	<Menu_Access Enabled='true'/>
	...
	<Toggle_Peer_Override Enabled="true" Permissions="true"/>	
	<Toggle_Local_Override Enabled="true" Permissions="true"/>
	...
	<Menu_Plugins Enabled="true"/>
</MENU>
```

In the example above, we've added `Permissions="true"` after the enable attribute. It is important to note that the `Enabled` attribute must be true, it acts as an end-all-be-all switch. Permissions can be added to any of the `<MENU>` elements, and are optional so you only need to add this attribute to the menu items you wish to limit access to.

#### Add Ace Config / Permissions Lines

```actionscript
add_ace builtin.everyone "LVC:Fleet.menu_access" allow
add_ace builtin.everyone "LVC:Fleet.menu_main_siren_settings" allow
add_ace builtin.everyone "LVC:Fleet.toggle_peer_override" allow
add_ace builtin.everyone "LVC:Fleet.toggle_local_override" allow
add_ace builtin.everyone "LVC:Fleet.toggle_airhorn_intrp" allow
add_ace builtin.everyone "LVC:Fleet.toggle_reset_standby" allow
add_ace builtin.everyone "LVC:Fleet.custom_tone_options" allow
add_ace builtin.everyone "LVC:Fleet.custom_manual" allow
add_ace builtin.everyone "LVC:Fleet.custom_auxiliary" allow
add_ace builtin.everyone "LVC:Fleet.toggle_park_kill" allow
add_ace builtin.everyone "LVC:Fleet.menu_hud_settings" allow
add_ace builtin.everyone "LVC:Fleet.toggle_hud" allow
add_ace builtin.everyone "LVC:Fleet.custom_backlight_mode" allow
add_ace builtin.everyone "LVC:Fleet.menu_audio_settings" allow
add_ace builtin.everyone "LVC:Fleet.toggle_radio" allow
add_ace builtin.everyone "LVC:Fleet.custom_scheme" allow
add_ace builtin.everyone "LVC:Fleet.toggle_clicks" allow
add_ace builtin.everyone "LVC:Fleet.custom_activity_reminder" allow
add_ace builtin.everyone "LVC:Fleet.menu_plugins" allow
```

Change the `builtin.everyone` to the ace group you'd like to authorize, just like any other resource.

{% hint style="info" %}
`Menu_Access` in both VCF and ace permissions controls the menu as a whole, so you don't need to add every menu item if you intend on disabling the menu entirely.
{% endhint %}


# In Game Use Guide

Instructions on how to use LVC:Fleet in game

### In Game Menu Usage

{% content-ref url="/pages/flWNfGKSVzacSWmtQOMG" %}
[LVC:Fleet Menu](/fleet/in-game-use-guide/lvc-fleet-menu)
{% endcontent-ref %}

### Rumbler / Howler Usage

#### Prerequisites

1. Rumbler string, ref, bank set in VCF. See [Horns & Sirens Element](/fleet/resource-installation/customize-vcfs#horns-sirens-elements).
2. Local Override not enabled.
3. Siren activated.

If all prerequisites are met pressing `LSHIFT+E`will toggle Rumbler. The Rumbler will only run for 5 seconds before turning off, this duration can be set in the menu.&#x20;

{% hint style="info" %}
**Future feature**: customize rumbler duration using VCF file.
{% endhint %}

## Commands

`/lvcdebug` - print debug messages to the console and front-end.

`/lvclock` - lock out controls.

`/lvcrecovercrash` - attempt to recover from a crash state.

`/lvcfactoryreset` - executes same as the button in the menu, clears local save data.


# LVC:Fleet Menu

RageUI menu for LVC:F.

### Main Menu

The LVC:Fleet menu can be opened by default using `O` as in Oscar this can be changed in [base settings](/fleet/resource-installation/configure-base-settings#register-key-maps).&#x20;

<div align="left"><figure><img src="/files/n9JED66Nt058RFI3Y6JX" alt=""><figcaption><p>LVC:Fleet RageUI Menu</p></figcaption></figure></div>

#### Profile

If multiple profiles are approved (assigned in [Assign Profiles](https://docs.luxartengineering.com/fleet/resource-installation/configure-base-settings#assign-profiles)) *Profile* menu item will change which profile is currently being used. Changing this will reset un-saved settings for the current profile and load new profile settings.

#### Local Override

Selecting this will disable any assigned server side sirens for your vehicle and revert to client side siren. Currently, other players will here their client side sirens for your vehicle.&#x20;

#### Peer Override

Selecting this will override other players siren with your selected profile settings, if and only if, both profiles are of the same faction. See [VCFRoot Attributes](/fleet/resource-installation/customize-vcfs#vcfroot-attributes).

#### Primary Manual Tone

Change which tone is played when the cycle key (`R`) is held. Pressing Enter will open a tone rename window.

#### Secondary Manual Tone

Change which tone is played when the cycle key (`R`) and horn key (`E`) are held. Pressing Enter will open a tone rename window.

#### Auxiliary Siren Tone

Change which tone is played when the auxiliary siren (`up-arrow`). Pressing Enter will open a tone rename window.&#x20;

### Main Siren Settings

<div align="left"><figure><img src="/files/zR1bpSOtoxcQHXL2j1He" alt=""><figcaption></figcaption></figure></div>

#### Airhorn Interrupt Mode

When vehicle siren is activated and the airhorn is activated, stop the siren and play only the airhorn. Otherwise, play both the siren and airhorn overtop of eachother.

#### Reset to Standby

Reset siren back to position 1 or the first siren tone when the siren is toggled. Otherwise, resume playing the previous tone.

#### Siren Park Kill

When the siren is activated and the player exits the vehicle, turn the siren off.

#### Tone Options

Each tone will be listed, the arrow keys will switch between *Cycle & Button, Cycle Only, Button Only, Disabled.* Where *Cycle* means played when `R` cycle siren button is pressed; *Button* is using the on-demand registered siren keys (default: `numrow1-0`); *Disabled* prevents the siren from playing at all.

Selecting the item using the Enter will allow players to rename the tones.

### HUD Settings

<div align="left"><figure><img src="/files/vF6yVzyq3mAYINZvybZA" alt=""><figcaption></figcaption></figure></div>

#### Enabled

Toggle on screen siren controller HUD.

#### Move Mode

Selecting this enables NUI cursor, drag-and-drop the HUD to your desired location. Pressing right-click, Esc, Spacebar will exit move mode and save the HUDs location.

#### Scale

Change the size of siren controller HUD and save HUD scale.

#### Backlight

Changes HUD backlight mode. Auto: based on headlight state; Off: always off; On: always on.

#### Reset

Repositions HUD to it's default position. This can be used if the HUD is off screen.

### Audio Settings

<div align="left"><figure><img src="/files/AsGjHSjdHqyP5eA3je6F" alt=""><figcaption></figcaption></figure></div>

#### Radio Controls

Toggles radio wheel functionality. By default holding the tilde key `` ` ``, located left of numrow 1, will open GTA V FM-radio wheel.

#### Siren Box Scheme

Changes which audio files are used for button sound effects. To change these see [Audio Element](/fleet/resource-installation/customize-vcfs#audio-element).

#### Manual Button Clicks

Determines if button sound effects are played when the manual siren keys (`R`) & (`R+E`) are pressed/released.

#### Airhorn Button Clicks

Determines if button sound effects are played when the horn key (`E`) is pressed / released.

#### Activity Reminder

When enabled, play reminder tone to the player if the emergency lights have been active for the selected amount of time is minutes and no siren controller key has been pressed. &#x20;

#### Adjust Volumes Menu

Allows for changing of sound effect volumes via slider. Pressing enter on a volume item will play it.

### Storage Management Menu

<div align="left"><figure><img src="/files/6NrdTqez38Cof9N9H0LB" alt=""><figcaption></figcaption></figure></div>

#### Save Settings

Save LVC:Fleet configuration and selected profile to players PC by the use of KVPs. On the right side of this button you can see the detected profile name in parenthesis, in this example 'LAPD'.

#### Load Settings

Load LVC:Fleet configuration and attempt to select the saved profile, if approved. On the right side of this button you can see the detected profile name in parenthesis, in this example 'LAPD'.

#### Copy Settings

Using this menu, players can copy configurations from other profiles if both profiles have the same approved tones. *Coming soon!*

#### Reset Settings

Reverts LVC:Fleet configuration to its default settings as outlined in the VCF. Useful for debugging.

#### Factory Reset

Deletes all LVC:Fleet saves and resets LVC:Fleet configuration to its default settings as outlined in VCF. Useful for debugging.


# Resource Installation

Instructions on how to install LVC:v3 into your server.

#### Download the latest stable release `Luxart.Vehicle.Control.vX.X.X.zip` (not source code) from [releases](https://github.com/TrevorBarns/luxart-vehicle-control/releases).

1. **Copy `RageUI` folder from 'dependencies' folder in resources folder.**

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><em>LVC utilizes a modified release of RageUI, please install it even if you already have another version installed.</em></p></div>
2. **Copy `lvc` folder to resources folder.**

   <div data-gb-custom-block data-tag="hint" data-style="warning" class="hint hint-warning"><p><em>Make sure your resource is named <code>lvc</code> it is required.</em></p></div>
3. **Add `ensure lvc` to server.cfg.**
4. **(*****Optional*****) Install any desired plugins from plugins folder to `lvc/PLUGINS/` (*****see*** [***shared plugins***](/shared-plugins/introduction-to-plugins)**)**

{% hint style="info" %}
This resource utilizes [globbing](https://docs.fivem.net/docs/scripting-reference/resource-manifest/resource-manifest/#globbing) which may not be supported in some linux environments. Most releases include `fxmanifest.for.Linux.Servers.no.globbing.zip` which contain a compatible fxmainfest.lua without globbing.
{% endhint %}

{% hint style="info" %}
If you are updating make sure to run `refresh` before restarting LVC:v3, this ensures new files that were added will be loaded.
{% endhint %}


# Configure Base Settings

Configuration of fundamental settings located in SETTINGS.lua.

### Default Settings

Configure settings to your liking. Items with prefix/postfix 'default' means the end player will be able to modify/override these later.

### Set a Community

This unique set of characters for your community will be used for profile saving.

* The ID should be 4-6 alphanumerical characters.
* Spaces are not allowed and will not work, dashes can be used instead.
* Some examples may be your servers abbreviation, name, etc.
  * **Examples:**\
    `'LCPS'`, `'LCPSR'`, `'SARP'`, `'LSDOJ'`, `'JakesRP'`, etc.

{% hint style="info" %}
The purpose of this string is to differentiate the client side saves between servers. Since it is possible (and likely) that servers may use the same profile names, but different profile siren assignments.
{% endhint %}

{% hint style="warning" %}
This string should be set once, and never changed as it will result in loss of LVC:Fleet saves for all players. It is not public facing so even if the server name changes it does not need to change.
{% endhint %}

### Configure Controls

#### Register Key Maps

Users may change these in their GTA V > Settings > Hotkeys > FiveM settings.\
More info: [CFX Cookbook - How RegisterKeyMappings Work](https://cookbook.fivem.net/2020/01/06/using-the-new-console-key-bindings/)\
List of Keys\*\*:\*\* [RegisterKeyMap Supported Keys](https://pastebin.com/u9ewvWWZ)

`open_menu_key`: sets default key for opening LVC:v3 Menu.\
`lockout_default_key`: sets default key for toggling LVC:v3 control lock, which disabled all controls.

**Indicator Controls**

These static keys cannot be changed by the end user and support controller keys as well.\
List of Keys\*\*:\*\* [CFX Game Reference - Controls](https://docs.fivem.net/docs/game-references/controls/)

`hazard_key`*:* when held for `hazard_hold_duration` toggle 4-way flashers.\
`left_signal_key`: toggle left turn signal.\
`right_signal_key`: toggle right turn signal.


# Configure Sirens

How to define siren tones in SIRENS table located in SIRENS.lua.

**Example Sirens Table (w/o server sided sirens)**

{% code title="SIRENS.lua" %}

```lua
SIRENS = {
--[[1]]	  { Name = "Airhorn", 		String = "SIRENS_AIRHORN", 				Ref = 0 }, --1
--[[2]]	  { Name = "Wail", 		String = "VEHICLES_HORNS_SIREN_1", 			Ref = 0 }, --2
--[[3]]	  { Name = "Yelp", 		String = "VEHICLES_HORNS_SIREN_2",	 		Ref = 0 }, --3
--[[4]]	  { Name = "Priority", 		String = "VEHICLES_HORNS_POLICE_WARNING", 		Ref = 0 }, --4		
--[[5]]	  { Name = "Futura", 		String = "RESIDENT_VEHICLES_SIREN_WAIL_01", 		Ref = 0 }, --5
--[[6]]	  { Name = "Hetro", 		String = "RESIDENT_VEHICLES_SIREN_WAIL_02", 		Ref = 0 }, --6
--[[7]]	  { Name = "Sweep-1", 		String = "RESIDENT_VEHICLES_SIREN_WAIL_03", 		Ref = 0 }, --7
--[[8]]	  { Name = "Sweep-2", 		String = "RESIDENT_VEHICLES_SIREN_QUICK_01", 		Ref = 0 }, --8
--[[9]]	  { Name = "Hi-Low",		String = "RESIDENT_VEHICLES_SIREN_QUICK_02",		Ref = 0 }, --9
--[[10]]  { Name = "Whine Down",	String = "RESIDENT_VEHICLES_SIREN_QUICK_03", 		Ref = 0 }, --10
--[[11]]  { Name = "Powercall", 	String = "VEHICLES_HORNS_AMBULANCE_WARNING", 		Ref = 0 }, --11
--[[12]]  { Name = "QSiren", 		String = "VEHICLES_HORNS_FIRETRUCK_WARNING", 		Ref = 0 }, --12
--[[13]]  { Name = "Fire Yelp", 	String = "RESIDENT_VEHICLES_SIREN_FIRETRUCK_WAIL_01", 	Ref = 0 }, --13
--[[14]]  { Name = "Fire Yelp", 	String = "RESIDENT_VEHICLES_SIREN_FIRETRUCK_QUICK_01", 	Ref = 0 }, --14
}
```

{% endcode %}

* For most users, **`Name`** is the only field that needs to be modified. It determines the default name for each tone and will be displayed in LVC:v3 Menu, these can be generic like "Siren 1, Siren 2, etc." or specific based on departments recommended siren. The end user will be able to change these.
* For advanced users:
  * **`String`** and **`Ref`** can be changed to change which audio file is pulled based on tone. Rearranging default resident.rpf names is not recommended as it serves no benefit. Instead rearranging the siren assignments order would be easier. The only time changing `String` and `Ref` would be recommended is for integration of server side siren integration. See [Server Sided Audio Integration](https://github.com/TrevorBarns/luxart-vehicle-control/wiki/Server-Sided-Audio-Integration).
  * **`Option`** an additional key can be added to each tones table determines the default option state that each tone is in. The end user can change these later.\
    *Example:* `{ Name = "CustomName", String = "SIREN_STRING", Ref = 0, Option = 1 },`

    <table><thead><tr><th width="162.70103092783506" align="center">Option Value</th><th width="188" align="center">Behavior</th></tr></thead><tbody><tr><td align="center">1</td><td align="center">Cycle &#x26; Button</td></tr><tr><td align="center">2</td><td align="center">Cycle Only</td></tr><tr><td align="center">3</td><td align="center">Button Only</td></tr><tr><td align="center">4</td><td align="center">Disabled</td></tr></tbody></table>


# Assign Sirens

How to assign sirens to vehicles using SIREN\_ASSIGNMENTS table in SIRENS.lua,

### SIREN\_ASSIGNEMENTS Table

{% code title="SIRENS.lua" %}

```lua
SIREN_ASSIGNMENTS = {
--['<gameName>'] = { <airhorn tone>, <siren tone-1>, <siren tone-2>, ... <siren tone-n> },
['DEFAULT'] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, 
['FIRETRUK'] = { 12, 13, 14, 11 }, 
['AMBULAN'] = { 1, 2, 3, 4, 11 }, 
['LGUARD'] = { 1, 2, 3, 4, 11 },
}
```

{% endcode %}

In this table you can add additional vehicles for assignment using the vehicles `<gameName>` exactly as found in `vehicles.meta`. **It is case sensitive**.

<details>

<summary>vehicles.meta example:</summary>

```xml
...
<modelName>so2</modelName> <!-- SPAWN NAME -->
<handlingId>so2</handlingId>
<gameName>so2</gameName> <!-- GAME NAME (WHAT LVC USES) -->
<vehicleMakeName />
<expressionDictName>null</expressionDictName>
...
```

</details>

* Both R\* and LVC:v3 truncate down to 11 characters. **It is important that the first 11 characters are unique.**
  * **Example**:\
    If my addon vehicles `<gameName>` is "*2008 Ford CVPI CHP*" and I have another vehicle "*2008 Ford CVPI LSPD*" both of these after truncate equate to "*2008 Ford C*" therefor LVC:v3 will not be able to differentiate these.&#x20;

{% hint style="danger" %}
**The default or fallback key `['DEFAULT']` should always be present and never removed. Doing so will result in issues.**
{% endhint %}

### **Wildcards**

Supported Wildcards:

* `#` represents 1 or more digits.

#### How it works:

1. LVC:v3 checks for vehicle profile matching game name. *e.g.* `['2008fpiu1']`
2. If not found, attempts wildcard search, meaning wildcards will be used *secondary* to custom profiles. *e.g.* `['2008fpiu#']`
3. If not found, attempts a less specific wildcard search, leading and trailing numbers. *e.g.* `['#fpiu#']` *(v3.2.7)*
4. If not found, use default profile. *e.g.* `['DEFAULT']`

*Example*:\
\* `['veh#'] = { ... }` will be used for vehicles with game names `veh1`, `veh2`, ..., `veh9999`, etc. where exact profile not found.

{% hint style="info" %}
Examples and premade packs can be found here: [LVC:v3 Extras](https://github.com/TrevorBarns/luxart-vehicle-control-extras/).
{% endhint %}


# Advanced Configuration

Debugging and advanced configuration functionality.

### Debug Mode

To temporarily toggle *debug mode* use chat command `/lvcdebug` this resets on resource restart. For persistent debug mode use convar below.

### **Resource Convars (fxmanifest.lua)**

* `beta_checking` enables beta version notifications to server console.
* `experimental` will mute experimental messages for server console.
* `debug_mode` increases console logging for client, prints \<gameName> of vehicle if no profile was found.

{% hint style="info" %}
Changing covars require the `refresh` command to be ran first, then restart the resource for changes to take effect.
{% endhint %}

### Custom HUD

#### Custom Graphics

The in game siren controller display or heads-up-display UI can be modified to your liking, you will need an understanding of HTML, Javascript, and NUI.&#x20;

{% hint style="info" %}
Support is limited in this area.
{% endhint %}

#### Move Default HUD location

All HUD related functions/code is located in the UI folder. The default position of the HUD is set in `UI/html/style.css`.

```css
#sirenbox {
	display: none;
	position: absolute;
	overflow: hidden;
	width: 602px;
	height: 161px;
	left: 0%;
	top: 68%;
	transform-origin: left top;
	transform: scale(0.6);
	background-image: url("../textures/background.png");
}
```

**The relevant attributes are:&#x20;*****left*****,&#x20;*****top*****, and&#x20;*****transform-origin*****.**

* *left* determines how far in percentage of the screen resolution should the HUD be placed from the left edge. If you wanted to right align the HUD you could change this to `right: XX%`, 0% being against the right edge of the display.
* *top* determines how far down from the top the HUD should be placed.
* *transform-origin* attribute determines which way the HUD should expand on size adjustment. For a bottom right aligned HUD you would want the transform-origin to be `right bottom`. This ensures that the HUD does not expand outside of the screen space.

### Custom Audio Schemes

Custom front end sound effects can be added. Create a new folder in `/UI/sounds` with the desired name of your scheme.

{% hint style="warning" %}
Sound scheme names cannot have any spaces in them.
{% endhint %}

Add scheme name to `button_sfx_scheme_choices` in SETTINGS.lua.


# Server Sided Siren Integration

Stream custom sirens from the server to LVC:v3

{% embed url="<https://www.youtube.com/watch?v=KSEyeDQf5VQ>" %}

### Introduction

Below are two third-party resources that allow for streaming of R\* audio files from server to client. These audio files can be for various things but some people use them for sirens.

* **Server-Sided-Sounds-and-Sirens (SAS)**\
  Supports up to 214 tones for FREE. I am in no way affiliated with this resource or its creator.&#x20;

{% embed url="<https://github.com/fk-1997/Server-Sided-Sounds-and-Sirens>" %}
Server Sided Sounds and Sirens Github
{% endembed %}

* **WM-ServerSirens (WM-SS)**\
  Provides 8 tones for free, but for more there is a paywall. I am in no way affiliated with 'Walshey Modifications' or this resource.

{% embed url="<https://forum.cfx.re/t/release-wm-serversirens-fivem-server-side-siren-resource-walshey-marcus/1491908>" %}
WM-ServerSirens Release Page CFX
{% endembed %}

***

### How to Integrate:

### 1. Request Audio Bank:

First we need to request the audio bank, this loads the audio for the client prior to use. We can place these lines anywhere in SIRENS.lua.

{% hint style="warning" %}
Currently only 7 audio banks are supported. We are not sure why, seems like a FiveM lua limitation.
{% endhint %}

**Server-Sided-Sounds-and-Sirens:**\
Below are the audio banks supported by SAS. **You only need to request audio banks you intend to use.** All audio banks below support 6 tones each, besides the last one, OISS\_SSA\_VEHAUD\_ETC, which supports 16 tones.

```lua
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSPD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSPD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSSD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSSD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_BCSO_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_BCSO_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SAHP_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SAHP_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SAHP_BIKE", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_NOOSE_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_NOOSE_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_FIB_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_FIB_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_RHPD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_RHPD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_DPPD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_DPPD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSIA_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSIA_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSPP_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSPP_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSFD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSFD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSCOFD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_LSCOFD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_BCFD_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_BCFD_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SANFIRE_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SANFIRE_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SAMS_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_SAMS_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_USFS_NEW", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_USFS_OLD", false)
RequestScriptAudioBank("DLC_SERVERSIDEAUDIO\\OISS_SSA_VEHAUD_ETC", false)
```

**WM-ServerSirens**:

* Free:

  ```lua
  RequestScriptAudioBank("DLC_WMSIRENS\\SIRENPACK_ONE", false)
  ```
* Paid:

  ```lua
  RequestScriptAudioBank("DLC_WALSHEY\\SIRENPACK_ONE", false)
  RequestScriptAudioBank("DLC_WALSHEY\\SIRENPACK_TWO", false)
  RequestScriptAudioBank("DLC_WALSHEY\\SIRENPACK_THREE", false)
  RequestScriptAudioBank("DLC_WALSHEY\\SIRENPACK_FOUR", false)
  ```

*Example:*

<figure><img src="https://camo.githubusercontent.com/54fbf1ef00b524db8ed9b5c32ec8e124e98024eafa9a4a08732977bf30a2e1ef/68747470733a2f2f692e6779617a6f2e636f6d2f62303231343339363132346665366134663866343865396238316665343830342e706e67" alt=""><figcaption><p>SIRENS.lua</p></figcaption></figure>

{% hint style="warning" %}
Make sure you are using ASCII quotes not UTF8 quotes from CFX forum post. Correct: " vs Incorrect: “. This will result in a parsing error and many other errors as SIRENS.lua file will not be loaded.
{% endhint %}

### 2. Configuration of SIRENS table (SIRENS.lua)

Now that we have told GTA V to load the requested audio banks from Step 1, we now need to create the specific tones.

* To add additional tones copy & paste additional lines into the SIRENS table.
  * Take note of the incrementing numbers, they are the siren IDs and we will need them to assign sirens later. These are not generated so you may have to manually renumber lines.
  * You can change the name to your desired siren name such as 'Wail', 'Yelp', '295-Wail', 'FSS-Rumbler'. See: [Configure Sirens](/v3/resource-installation/configure-sirens) for more information.

<details>

<summary>Server-Side-Sirens-and-Sounds Example</summary>

[View Raw / View in New Tab](https://pastebin.com/raw/jM98Pjtt)

{% code title="SIRENS.lua > Sirens Table" %}

```lua
SIRENS = {
--[[1]]   { Name = "Airhorn",       String = "SIRENS_AIRHORN",                              Ref = 0 }, --1
--[[2]]   { Name = "Wail",          String = "VEHICLES_HORNS_SIREN_1",                      Ref = 0 }, --2
--[[3]]   { Name = "Yelp",          String = "VEHICLES_HORNS_SIREN_2",                      Ref = 0 }, --3
--[[4]]   { Name = "Priority",      String = "VEHICLES_HORNS_POLICE_WARNING",               Ref = 0 }, --4
--[[5]]   { Name = "Futura",        String = "RESIDENT_VEHICLES_SIREN_WAIL_01",             Ref = 0 }, --5
--[[6]]   { Name = "Hetro",         String = "RESIDENT_VEHICLES_SIREN_WAIL_02",             Ref = 0 }, --6
--[[7]]   { Name = "Sweep-1",       String = "RESIDENT_VEHICLES_SIREN_WAIL_03",             Ref = 0 }, --7
--[[8]]   { Name = "Sweep-2",       String = "RESIDENT_VEHICLES_SIREN_QUICK_01",            Ref = 0 }, --8
--[[9]]   { Name = "Hi-Low",        String = "RESIDENT_VEHICLES_SIREN_QUICK_02",            Ref = 0 }, --9
--[[10]]  { Name = "Whine Down",    String = "RESIDENT_VEHICLES_SIREN_QUICK_03",            Ref = 0 }, --10
--[[11]]  { Name = "Powercall",     String = "VEHICLES_HORNS_AMBULANCE_WARNING",            Ref = 0 }, --11
--[[12]]  { Name = "QSiren",        String = "VEHICLES_HORNS_FIRETRUCK_WARNING",            Ref = 0 }, --12
--[[13]]  { Name = "Fire Yelp",     String = "RESIDENT_VEHICLES_SIREN_FIRETRUCK_WAIL_01",   Ref = 0 }, --13
--[[14]]  { Name = "Fire Yelp",     String = "RESIDENT_VEHICLES_SIREN_FIRETRUCK_QUICK_01",  Ref = 0 }, --14
-- START OF SAS --
--[[15]]  { Name = "New LSPD HORN",         String = "OISS_SSA_VEHAUD_LSPD_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_LSPD_NEW_SOUNDSET"}, --15
--[[16]]  { Name = "New LSPD ADAM",         String = "OISS_SSA_VEHAUD_LSPD_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSPD_NEW_SOUNDSET"}, --16
--[[17]]  { Name = "New LSPD BOY",          String = "OISS_SSA_VEHAUD_LSPD_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSPD_NEW_SOUNDSET"}, --17
--[[18]]  { Name = "New LSPD CHARLES",      String = "OISS_SSA_VEHAUD_LSPD_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSPD_NEW_SOUNDSET"}, --18
--[[19]]  { Name = "New LSPD DAVID",        String = "OISS_SSA_VEHAUD_LSPD_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSPD_NEW_SOUNDSET"}, --19
--[[20]]  { Name = "New LSPD EDWARD",       String = "OISS_SSA_VEHAUD_LSPD_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSPD_NEW_SOUNDSET"}, --20
--[[21]]  { Name = "Old LSPD HORN",         String = "OISS_SSA_VEHAUD_LSPD_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_LSPD_OLD_SOUNDSET"}, --21
--[[22]]  { Name = "Old LSPD ADAM",         String = "OISS_SSA_VEHAUD_LSPD_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSPD_OLD_SOUNDSET"}, --22
--[[23]]  { Name = "Old LSPD BOY",          String = "OISS_SSA_VEHAUD_LSPD_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSPD_OLD_SOUNDSET"}, --23
--[[24]]  { Name = "Old LSPD CHARLES",      String = "OISS_SSA_VEHAUD_LSPD_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSPD_OLD_SOUNDSET"}, --24
--[[25]]  { Name = "Old LSPD DAVID",        String = "OISS_SSA_VEHAUD_LSPD_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSPD_OLD_SOUNDSET"}, --25
--[[26]]  { Name = "Old LSPD EDWARD",       String = "OISS_SSA_VEHAUD_LSPD_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSPD_OLD_SOUNDSET"}, --26
--[[27]]  { Name = "New LSSD HORN",         String = "OISS_SSA_VEHAUD_LSSD_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_LSSD_NEW_SOUNDSET"}, --27
--[[28]]  { Name = "New LSSD ADAM",         String = "OISS_SSA_VEHAUD_LSSD_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSSD_NEW_SOUNDSET"}, --28
--[[29]]  { Name = "New LSSD BOY",          String = "OISS_SSA_VEHAUD_LSSD_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSSD_NEW_SOUNDSET"}, --29
--[[30]]  { Name = "New LSSD CHARLES",      String = "OISS_SSA_VEHAUD_LSSD_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSSD_NEW_SOUNDSET"}, --30
--[[31]]  { Name = "New LSSD DAVID",        String = "OISS_SSA_VEHAUD_LSSD_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSSD_NEW_SOUNDSET"}, --31
--[[32]]  { Name = "New LSSD EDWARD",       String = "OISS_SSA_VEHAUD_LSSD_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSSD_NEW_SOUNDSET"}, --32
--[[33]]  { Name = "Old LSSD HORN",         String = "OISS_SSA_VEHAUD_LSSD_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_LSSD_OLD_SOUNDSET"}, --33
--[[34]]  { Name = "Old LSSD ADAM",         String = "OISS_SSA_VEHAUD_LSSD_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSSD_OLD_SOUNDSET"}, --34
--[[35]]  { Name = "Old LSSD BOY",          String = "OISS_SSA_VEHAUD_LSSD_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSSD_OLD_SOUNDSET"}, --35
--[[36]]  { Name = "Old LSSD CHARLES",      String = "OISS_SSA_VEHAUD_LSSD_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSSD_OLD_SOUNDSET"}, --36
--[[37]]  { Name = "Old LSSD DAVID",        String = "OISS_SSA_VEHAUD_LSSD_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSSD_OLD_SOUNDSET"}, --37
--[[38]]  { Name = "Old LSSD EDWARD",       String = "OISS_SSA_VEHAUD_LSSD_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSSD_OLD_SOUNDSET"}, --38
--[[39]]  { Name = "New BCSO HORN",         String = "OISS_SSA_VEHAUD_BCSO_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET"}, --39
--[[40]]  { Name = "New BCSO ADAM",         String = "OISS_SSA_VEHAUD_BCSO_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET"}, --40
--[[41]]  { Name = "New BCSO BOY",          String = "OISS_SSA_VEHAUD_BCSO_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET"}, --41
--[[42]]  { Name = "New BCSO CHARLES",      String = "OISS_SSA_VEHAUD_BCSO_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET"}, --42
--[[43]]  { Name = "New BCSO DAVID",        String = "OISS_SSA_VEHAUD_BCSO_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET"}, --43
--[[44]]  { Name = "New BCSO EDWARD",       String = "OISS_SSA_VEHAUD_BCSO_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_BCSO_NEW_SOUNDSET"}, --44
--[[45]]  { Name = "Old BCSO HORN",         String = "OISS_SSA_VEHAUD_BCSO_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_BCSO_OLD_SOUNDSET"}, --45
--[[46]]  { Name = "Old BCSO ADAM",         String = "OISS_SSA_VEHAUD_BCSO_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_BCSO_OLD_SOUNDSET"}, --46
--[[47]]  { Name = "Old BCSO BOY",          String = "OISS_SSA_VEHAUD_BCSO_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_BCSO_OLD_SOUNDSET"}, --47
--[[48]]  { Name = "Old BCSO CHARLES",      String = "OISS_SSA_VEHAUD_BCSO_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_BCSO_OLD_SOUNDSET"}, --48
--[[49]]  { Name = "Old BCSO DAVID",        String = "OISS_SSA_VEHAUD_BCSO_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_BCSO_OLD_SOUNDSET"}, --49
--[[50]]  { Name = "Old BCSO EDWARD",       String = "OISS_SSA_VEHAUD_BCSO_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_BCSO_OLD_SOUNDSET"}, --50
--[[51]]  { Name = "New SAHP HORN",         String = "OISS_SSA_VEHAUD_SAHP_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_SAHP_NEW_SOUNDSET"}, --51
--[[52]]  { Name = "New SAHP ADAM",         String = "OISS_SSA_VEHAUD_SAHP_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_SAHP_NEW_SOUNDSET"}, --52
--[[53]]  { Name = "New SAHP BOY",          String = "OISS_SSA_VEHAUD_SAHP_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_SAHP_NEW_SOUNDSET"}, --53
--[[54]]  { Name = "New SAHP CHARLES",      String = "OISS_SSA_VEHAUD_SAHP_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_SAHP_NEW_SOUNDSET"}, --54
--[[55]]  { Name = "New SAHP DAVID",        String = "OISS_SSA_VEHAUD_SAHP_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_SAHP_NEW_SOUNDSET"}, --55
--[[56]]  { Name = "New SAHP EDWARD",       String = "OISS_SSA_VEHAUD_SAHP_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_SAHP_NEW_SOUNDSET"}, --56
--[[57]]  { Name = "Old SAHP HORN",         String = "OISS_SSA_VEHAUD_SAHP_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_SAHP_OLD_SOUNDSET"}, --57
--[[58]]  { Name = "Old SAHP ADAM",         String = "OISS_SSA_VEHAUD_SAHP_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_SAHP_OLD_SOUNDSET"}, --58
--[[59]]  { Name = "Old SAHP BOY",          String = "OISS_SSA_VEHAUD_SAHP_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_SAHP_OLD_SOUNDSET"}, --59
--[[60]]  { Name = "Old SAHP CHARLES",      String = "OISS_SSA_VEHAUD_SAHP_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_SAHP_OLD_SOUNDSET"}, --60
--[[61]]  { Name = "Old SAHP DAVID",        String = "OISS_SSA_VEHAUD_SAHP_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_SAHP_OLD_SOUNDSET"}, --61
--[[62]]  { Name = "Old SAHP EDWARD",       String = "OISS_SSA_VEHAUD_SAHP_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_SAHP_OLD_SOUNDSET"}, --62
--[[63]]  { Name = "Bike SAHP HORN",        String = "OISS_SSA_VEHAUD_SAHP_BIKE_HORN",            Ref = "OISS_SSA_VEHAUD_SAHP_BIKE_SOUNDSET"}, --63
--[[64]]  { Name = "Bike SAHP ADAM",        String = "OISS_SSA_VEHAUD_SAHP_BIKE_SIREN_ADAM",      Ref = "OISS_SSA_VEHAUD_SAHP_BIKE_SOUNDSET"}, --64
--[[65]]  { Name = "Bike SAHP BOY",         String = "OISS_SSA_VEHAUD_SAHP_BIKE_SIREN_BOY",       Ref = "OISS_SSA_VEHAUD_SAHP_BIKE_SOUNDSET"}, --65
--[[66]]  { Name = "Bike SAHP CHARLES",     String = "OISS_SSA_VEHAUD_SAHP_BIKE_SIREN_CHARLES",   Ref = "OISS_SSA_VEHAUD_SAHP_BIKE_SOUNDSET"}, --66
--[[67]]  { Name = "Bike SAHP DAVID",       String = "OISS_SSA_VEHAUD_SAHP_BIKE_SIREN_DAVID",     Ref = "OISS_SSA_VEHAUD_SAHP_BIKE_SOUNDSET"}, --67
--[[68]]  { Name = "Bike SAHP EDWARD",      String = "OISS_SSA_VEHAUD_SAHP_BIKE_SIREN_EDWARD",    Ref = "OISS_SSA_VEHAUD_SAHP_BIKE_SOUNDSET"}, --68
--[[69]]  { Name = "New NOOSE HORN",        String = "OISS_SSA_VEHAUD_NOOSE_NEW_HORN",            Ref = "OISS_SSA_VEHAUD_NOOSE_NEW_SOUNDSET"}, --69
--[[70]]  { Name = "New NOOSE ADAM",        String = "OISS_SSA_VEHAUD_NOOSE_NEW_SIREN_ADAM",      Ref = "OISS_SSA_VEHAUD_NOOSE_NEW_SOUNDSET"}, --70
--[[71]]  { Name = "New NOOSE BOY",         String = "OISS_SSA_VEHAUD_NOOSE_NEW_SIREN_BOY",       Ref = "OISS_SSA_VEHAUD_NOOSE_NEW_SOUNDSET"}, --71
--[[72]]  { Name = "New NOOSE CHARLES",     String = "OISS_SSA_VEHAUD_NOOSE_NEW_SIREN_CHARLES",   Ref = "OISS_SSA_VEHAUD_NOOSE_NEW_SOUNDSET"}, --72
--[[73]]  { Name = "New NOOSE DAVID",       String = "OISS_SSA_VEHAUD_NOOSE_NEW_SIREN_DAVID",     Ref = "OISS_SSA_VEHAUD_NOOSE_NEW_SOUNDSET"}, --73
--[[74]]  { Name = "New NOOSE EDWARD",      String = "OISS_SSA_VEHAUD_NOOSE_NEW_SIREN_EDWARD",    Ref = "OISS_SSA_VEHAUD_NOOSE_NEW_SOUNDSET"}, --74
--[[75]]  { Name = "Old NOOSE HORN",        String = "OISS_SSA_VEHAUD_NOOSE_OLD_HORN",            Ref = "OISS_SSA_VEHAUD_NOOSE_OLD_SOUNDSET"}, --75
--[[76]]  { Name = "Old NOOSE ADAM",        String = "OISS_SSA_VEHAUD_NOOSE_OLD_SIREN_ADAM",      Ref = "OISS_SSA_VEHAUD_NOOSE_OLD_SOUNDSET"}, --76
--[[77]]  { Name = "Old NOOSE BOY",         String = "OISS_SSA_VEHAUD_NOOSE_OLD_SIREN_BOY",       Ref = "OISS_SSA_VEHAUD_NOOSE_OLD_SOUNDSET"}, --77
--[[78]]  { Name = "Old NOOSE CHARLES",     String = "OISS_SSA_VEHAUD_NOOSE_OLD_SIREN_CHARLES",   Ref = "OISS_SSA_VEHAUD_NOOSE_OLD_SOUNDSET"}, --78
--[[79]]  { Name = "Old NOOSE DAVID",       String = "OISS_SSA_VEHAUD_NOOSE_OLD_SIREN_DAVID",     Ref = "OISS_SSA_VEHAUD_NOOSE_OLD_SOUNDSET"}, --79
--[[80]]  { Name = "Old NOOSE EDWARD",      String = "OISS_SSA_VEHAUD_NOOSE_OLD_SIREN_EDWARD",    Ref = "OISS_SSA_VEHAUD_NOOSE_OLD_SOUNDSET"}, --80
--[[81]]  { Name = "New FIB HORN",          String = "OISS_SSA_VEHAUD_FIB_NEW_HORN",              Ref = "OISS_SSA_VEHAUD_FIB_NEW_SOUNDSET"},  --81
--[[82]]  { Name = "New FIB ADAM",          String = "OISS_SSA_VEHAUD_FIB_NEW_SIREN_ADAM",        Ref = "OISS_SSA_VEHAUD_FIB_NEW_SOUNDSET"},  --82
--[[83]]  { Name = "New FIB BOY",           String = "OISS_SSA_VEHAUD_FIB_NEW_SIREN_BOY",         Ref = "OISS_SSA_VEHAUD_FIB_NEW_SOUNDSET"},  --83
--[[84]]  { Name = "New FIB CHARLES",       String = "OISS_SSA_VEHAUD_FIB_NEW_SIREN_CHARLES",     Ref = "OISS_SSA_VEHAUD_FIB_NEW_SOUNDSET"},  --84
--[[85]]  { Name = "New FIB DAVID",         String = "OISS_SSA_VEHAUD_FIB_NEW_SIREN_DAVID",       Ref = "OISS_SSA_VEHAUD_FIB_NEW_SOUNDSET"},  --85
--[[86]]  { Name = "New FIB EDWARD",        String = "OISS_SSA_VEHAUD_FIB_NEW_SIREN_EDWARD",      Ref = "OISS_SSA_VEHAUD_FIB_NEW_SOUNDSET"},  --86
--[[87]]  { Name = "Old FIB HORN",          String = "OISS_SSA_VEHAUD_FIB_OLD_HORN",              Ref = "OISS_SSA_VEHAUD_FIB_OLD_SOUNDSET"},  --87
--[[88]]  { Name = "Old FIB ADAM",          String = "OISS_SSA_VEHAUD_FIB_OLD_SIREN_ADAM",        Ref = "OISS_SSA_VEHAUD_FIB_OLD_SOUNDSET"},  --88
--[[89]]  { Name = "Old FIB BOY",           String = "OISS_SSA_VEHAUD_FIB_OLD_SIREN_BOY",         Ref = "OISS_SSA_VEHAUD_FIB_OLD_SOUNDSET"},  --89
--[[90]]  { Name = "Old FIB CHARLES",       String = "OISS_SSA_VEHAUD_FIB_OLD_SIREN_CHARLES",     Ref = "OISS_SSA_VEHAUD_FIB_OLD_SOUNDSET"},  --90
--[[91]]  { Name = "Old FIB DAVID",         String = "OISS_SSA_VEHAUD_FIB_OLD_SIREN_DAVID",       Ref = "OISS_SSA_VEHAUD_FIB_OLD_SOUNDSET"},  --91
--[[92]]  { Name = "Old FIB EDWARD",        String = "OISS_SSA_VEHAUD_FIB_OLD_SIREN_EDWARD",      Ref = "OISS_SSA_VEHAUD_FIB_OLD_SOUNDSET"},  --92
--[[93]]  { Name = "New RHPD HORN",         String = "OISS_SSA_VEHAUD_RHPD_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_RHPD_NEW_SOUNDSET"}, --93
--[[94]]  { Name = "New RHPD ADAM",         String = "OISS_SSA_VEHAUD_RHPD_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_RHPD_NEW_SOUNDSET"}, --94
--[[95]]  { Name = "New RHPD BOY",          String = "OISS_SSA_VEHAUD_RHPD_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_RHPD_NEW_SOUNDSET"}, --95
--[[96]]  { Name = "New RHPD CHARLES",      String = "OISS_SSA_VEHAUD_RHPD_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_RHPD_NEW_SOUNDSET"}, --96
--[[97]]  { Name = "New RHPD DAVID",        String = "OISS_SSA_VEHAUD_RHPD_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_RHPD_NEW_SOUNDSET"}, --97
--[[98]]  { Name = "New RHPD EDWARD",       String = "OISS_SSA_VEHAUD_RHPD_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_RHPD_NEW_SOUNDSET"}, --98
--[[99]]  { Name = "Old RHPD HORN",         String = "OISS_SSA_VEHAUD_RHPD_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_RHPD_OLD_SOUNDSET"}, --99
--[[100]]  { Name = "Old RHPD ADAM",        String = "OISS_SSA_VEHAUD_RHPD_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_RHPD_OLD_SOUNDSET"}, --100
--[[101]]  { Name = "Old RHPD BOY",         String = "OISS_SSA_VEHAUD_RHPD_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_RHPD_OLD_SOUNDSET"}, --101
--[[102]]  { Name = "Old RHPD CHARLES",     String = "OISS_SSA_VEHAUD_RHPD_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_RHPD_OLD_SOUNDSET"}, --102
--[[103]]  { Name = "Old RHPD DAVID",       String = "OISS_SSA_VEHAUD_RHPD_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_RHPD_OLD_SOUNDSET"}, --103
--[[104]]  { Name = "Old RHPD EDWARD",      String = "OISS_SSA_VEHAUD_RHPD_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_RHPD_OLD_SOUNDSET"}, --104
--[[105]]  { Name = "New DPPD HORN",        String = "OISS_SSA_VEHAUD_DPPD_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_DPPD_NEW_SOUNDSET"}, --105
--[[106]]  { Name = "New DPPD ADAM",        String = "OISS_SSA_VEHAUD_DPPD_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_DPPD_NEW_SOUNDSET"}, --106
--[[107]]  { Name = "New DPPD BOY",         String = "OISS_SSA_VEHAUD_DPPD_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_DPPD_NEW_SOUNDSET"}, --107
--[[108]]  { Name = "New DPPD CHARLES",     String = "OISS_SSA_VEHAUD_DPPD_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_DPPD_NEW_SOUNDSET"}, --108
--[[109]]  { Name = "New DPPD DAVID",       String = "OISS_SSA_VEHAUD_DPPD_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_DPPD_NEW_SOUNDSET"}, --109
--[[110]]  { Name = "New DPPD EDWARD",      String = "OISS_SSA_VEHAUD_DPPD_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_DPPD_NEW_SOUNDSET"}, --110
--[[111]]  { Name = "Old DPPD HORN",        String = "OISS_SSA_VEHAUD_DPPD_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_DPPD_OLD_SOUNDSET"}, --111
--[[112]]  { Name = "Old DPPD ADAM",        String = "OISS_SSA_VEHAUD_DPPD_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_DPPD_OLD_SOUNDSET"}, --112
--[[113]]  { Name = "Old DPPD BOY",         String = "OISS_SSA_VEHAUD_DPPD_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_DPPD_OLD_SOUNDSET"}, --113
--[[114]]  { Name = "Old DPPD CHARLES",     String = "OISS_SSA_VEHAUD_DPPD_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_DPPD_OLD_SOUNDSET"}, --114
--[[115]]  { Name = "Old DPPD DAVID",       String = "OISS_SSA_VEHAUD_DPPD_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_DPPD_OLD_SOUNDSET"}, --115
--[[116]]  { Name = "Old DPPD EDWARD",      String = "OISS_SSA_VEHAUD_DPPD_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_DPPD_OLD_SOUNDSET"}, --116
--[[117]]  { Name = "New LSIA HORN",        String = "OISS_SSA_VEHAUD_LSIA_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_LSIA_NEW_SOUNDSET"}, --117
--[[118]]  { Name = "New LSIA ADAM",        String = "OISS_SSA_VEHAUD_LSIA_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSIA_NEW_SOUNDSET"}, --118
--[[119]]  { Name = "New LSIA BOY",         String = "OISS_SSA_VEHAUD_LSIA_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSIA_NEW_SOUNDSET"}, --119
--[[120]]  { Name = "New LSIA CHARLES",     String = "OISS_SSA_VEHAUD_LSIA_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSIA_NEW_SOUNDSET"}, --120
--[[121]]  { Name = "New LSIA DAVID",       String = "OISS_SSA_VEHAUD_LSIA_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSIA_NEW_SOUNDSET"}, --121
--[[122]]  { Name = "New LSIA EDWARD",      String = "OISS_SSA_VEHAUD_LSIA_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSIA_NEW_SOUNDSET"}, --122
--[[123]]  { Name = "Old LSIA HORN",        String = "OISS_SSA_VEHAUD_LSIA_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_LSIA_OLD_SOUNDSET"}, --123
--[[124]]  { Name = "Old LSIA ADAM",        String = "OISS_SSA_VEHAUD_LSIA_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSIA_OLD_SOUNDSET"}, --124
--[[125]]  { Name = "Old LSIA BOY",         String = "OISS_SSA_VEHAUD_LSIA_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSIA_OLD_SOUNDSET"}, --125
--[[126]]  { Name = "Old LSIA CHARLES",     String = "OISS_SSA_VEHAUD_LSIA_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSIA_OLD_SOUNDSET"}, --126
--[[127]]  { Name = "Old LSIA DAVID",       String = "OISS_SSA_VEHAUD_LSIA_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSIA_OLD_SOUNDSET"}, --127
--[[128]]  { Name = "Old LSIA EDWARD",      String = "OISS_SSA_VEHAUD_LSIA_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSIA_OLD_SOUNDSET"}, --128
--[[129]]  { Name = "New LSPP HORN",        String = "OISS_SSA_VEHAUD_LSPP_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_LSPP_NEW_SOUNDSET"}, --129
--[[130]]  { Name = "New LSPP ADAM",        String = "OISS_SSA_VEHAUD_LSPP_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSPP_NEW_SOUNDSET"}, --130
--[[131]]  { Name = "New LSPP BOY",         String = "OISS_SSA_VEHAUD_LSPP_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSPP_NEW_SOUNDSET"}, --131
--[[132]]  { Name = "New LSPP CHARLES",     String = "OISS_SSA_VEHAUD_LSPP_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSPP_NEW_SOUNDSET"}, --132
--[[133]]  { Name = "New LSPP DAVID",       String = "OISS_SSA_VEHAUD_LSPP_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSPP_NEW_SOUNDSET"}, --133
--[[134]]  { Name = "New LSPP EDWARD",      String = "OISS_SSA_VEHAUD_LSPP_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSPP_NEW_SOUNDSET"}, --134
--[[135]]  { Name = "Old LSPP HORN",        String = "OISS_SSA_VEHAUD_LSPP_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_LSPP_OLD_SOUNDSET"}, --135
--[[136]]  { Name = "Old LSPP ADAM",        String = "OISS_SSA_VEHAUD_LSPP_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSPP_OLD_SOUNDSET"}, --136
--[[137]]  { Name = "Old LSPP BOY",         String = "OISS_SSA_VEHAUD_LSPP_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSPP_OLD_SOUNDSET"}, --137
--[[138]]  { Name = "Old LSPP CHARLES",     String = "OISS_SSA_VEHAUD_LSPP_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSPP_OLD_SOUNDSET"}, --138
--[[139]]  { Name = "Old LSPP DAVID",       String = "OISS_SSA_VEHAUD_LSPP_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSPP_OLD_SOUNDSET"}, --139
--[[140]]  { Name = "Old LSPP EDWARD",      String = "OISS_SSA_VEHAUD_LSPP_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSPP_OLD_SOUNDSET"}, --140
--[[141]]  { Name = "New LSFD HORN",        String = "OISS_SSA_VEHAUD_LSFD_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_LSFD_NEW_SOUNDSET"}, --141
--[[142]]  { Name = "New LSFD ADAM",        String = "OISS_SSA_VEHAUD_LSFD_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSFD_NEW_SOUNDSET"}, --142
--[[143]]  { Name = "New LSFD BOY",         String = "OISS_SSA_VEHAUD_LSFD_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSFD_NEW_SOUNDSET"}, --143
--[[144]]  { Name = "New LSFD CHARLES",     String = "OISS_SSA_VEHAUD_LSFD_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSFD_NEW_SOUNDSET"}, --144
--[[145]]  { Name = "New LSFD DAVID",       String = "OISS_SSA_VEHAUD_LSFD_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSFD_NEW_SOUNDSET"}, --145
--[[146]]  { Name = "New LSFD EDWARD",      String = "OISS_SSA_VEHAUD_LSFD_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSFD_NEW_SOUNDSET"}, --146
--[[147]]  { Name = "Old LSFD HORN",        String = "OISS_SSA_VEHAUD_LSFD_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_LSFD_OLD_SOUNDSET"}, --147
--[[148]]  { Name = "Old LSFD ADAM",        String = "OISS_SSA_VEHAUD_LSFD_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_LSFD_OLD_SOUNDSET"}, --148
--[[149]]  { Name = "Old LSFD BOY",         String = "OISS_SSA_VEHAUD_LSFD_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_LSFD_OLD_SOUNDSET"}, --149
--[[150]]  { Name = "Old LSFD CHARLES",     String = "OISS_SSA_VEHAUD_LSFD_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_LSFD_OLD_SOUNDSET"}, --150
--[[151]]  { Name = "Old LSFD DAVID",       String = "OISS_SSA_VEHAUD_LSFD_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_LSFD_OLD_SOUNDSET"}, --151
--[[152]]  { Name = "Old LSFD EDWARD",      String = "OISS_SSA_VEHAUD_LSFD_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_LSFD_OLD_SOUNDSET"}, --152
--[[153]]  { Name = "New LSCOFD HORN",      String = "OISS_SSA_VEHAUD_LSCOFD_NEW_HORN",           Ref = "OISS_SSA_VEHAUD_LSCOFD_NEW_SOUNDSET"}, --153
--[[154]]  { Name = "New LSCOFD ADAM",      String = "OISS_SSA_VEHAUD_LSCOFD_NEW_SIREN_ADAM",     Ref = "OISS_SSA_VEHAUD_LSCOFD_NEW_SOUNDSET"}, --154
--[[155]]  { Name = "New LSCOFD BOY",       String = "OISS_SSA_VEHAUD_LSCOFD_NEW_SIREN_BOY",      Ref = "OISS_SSA_VEHAUD_LSCOFD_NEW_SOUNDSET"}, --155
--[[156]]  { Name = "New LSCOFD CHARLES",   String = "OISS_SSA_VEHAUD_LSCOFD_NEW_SIREN_CHARLES",  Ref = "OISS_SSA_VEHAUD_LSCOFD_NEW_SOUNDSET"}, --156
--[[157]]  { Name = "New LSCOFD DAVID",     String = "OISS_SSA_VEHAUD_LSCOFD_NEW_SIREN_DAVID",    Ref = "OISS_SSA_VEHAUD_LSCOFD_NEW_SOUNDSET"}, --157
--[[158]]  { Name = "New LSCOFD EDWARD",    String = "OISS_SSA_VEHAUD_LSCOFD_NEW_SIREN_EDWARD",   Ref = "OISS_SSA_VEHAUD_LSCOFD_NEW_SOUNDSET"}, --158
--[[159]]  { Name = "Old LSCOFD HORN",      String = "OISS_SSA_VEHAUD_LSCOFD_OLD_HORN",           Ref = "OISS_SSA_VEHAUD_LSCOFD_OLD_SOUNDSET"}, --159
--[[160]]  { Name = "Old LSCOFD ADAM",      String = "OISS_SSA_VEHAUD_LSCOFD_OLD_SIREN_ADAM",     Ref = "OISS_SSA_VEHAUD_LSCOFD_OLD_SOUNDSET"}, --160
--[[161]]  { Name = "Old LSCOFD BOY",       String = "OISS_SSA_VEHAUD_LSCOFD_OLD_SIREN_BOY",      Ref = "OISS_SSA_VEHAUD_LSCOFD_OLD_SOUNDSET"}, --161
--[[162]]  { Name = "Old LSCOFD CHARLES",   String = "OISS_SSA_VEHAUD_LSCOFD_OLD_SIREN_CHARLES",  Ref = "OISS_SSA_VEHAUD_LSCOFD_OLD_SOUNDSET"}, --162
--[[163]]  { Name = "Old LSCOFD DAVID",     String = "OISS_SSA_VEHAUD_LSCOFD_OLD_SIREN_DAVID",    Ref = "OISS_SSA_VEHAUD_LSCOFD_OLD_SOUNDSET"}, --163
--[[164]]  { Name = "Old LSCOFD EDWARD",    String = "OISS_SSA_VEHAUD_LSCOFD_OLD_SIREN_EDWARD",   Ref = "OISS_SSA_VEHAUD_LSCOFD_OLD_SOUNDSET"}, --164
--[[165]]  { Name = "New BCFD HORN",        String = "OISS_SSA_VEHAUD_BCFD_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET"}, --165
--[[166]]  { Name = "New BCFD ADAM",        String = "OISS_SSA_VEHAUD_BCFD_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET"}, --166
--[[167]]  { Name = "New BCFD BOY",         String = "OISS_SSA_VEHAUD_BCFD_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET"}, --167
--[[168]]  { Name = "New BCFD CHARLES",     String = "OISS_SSA_VEHAUD_BCFD_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET"}, --168
--[[169]]  { Name = "New BCFD DAVID",       String = "OISS_SSA_VEHAUD_BCFD_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET"}, --169
--[[170]]  { Name = "New BCFD EDWARD",      String = "OISS_SSA_VEHAUD_BCFD_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_BCFD_NEW_SOUNDSET"}, --170
--[[171]]  { Name = "Old BCFD HORN",        String = "OISS_SSA_VEHAUD_BCFD_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_BCFD_OLD_SOUNDSET"}, --171
--[[172]]  { Name = "Old BCFD ADAM",        String = "OISS_SSA_VEHAUD_BCFD_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_BCFD_OLD_SOUNDSET"}, --172
--[[173]]  { Name = "Old BCFD BOY",         String = "OISS_SSA_VEHAUD_BCFD_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_BCFD_OLD_SOUNDSET"}, --173
--[[174]]  { Name = "Old BCFD CHARLES",     String = "OISS_SSA_VEHAUD_BCFD_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_BCFD_OLD_SOUNDSET"}, --174
--[[175]]  { Name = "Old BCFD DAVID",       String = "OISS_SSA_VEHAUD_BCFD_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_BCFD_OLD_SOUNDSET"}, --175
--[[176]]  { Name = "Old BCFD EDWARD",      String = "OISS_SSA_VEHAUD_BCFD_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_BCFD_OLD_SOUNDSET"}, --176
--[[177]]  { Name = "New SanFire HORN",     String = "OISS_SSA_VEHAUD_SANFIRE_NEW_HORN",          Ref = "OISS_SSA_VEHAUD_SANFIRE_NEW_SOUNDSET"}, --177
--[[178]]  { Name = "New SanFire ADAM",     String = "OISS_SSA_VEHAUD_SANFIRE_NEW_SIREN_ADAM",    Ref = "OISS_SSA_VEHAUD_SANFIRE_NEW_SOUNDSET"}, --178
--[[179]]  { Name = "New SanFire BOY",      String = "OISS_SSA_VEHAUD_SANFIRE_NEW_SIREN_BOY",     Ref = "OISS_SSA_VEHAUD_SANFIRE_NEW_SOUNDSET"}, --179
--[[180]]  { Name = "New SanFire CHARLES",  String = "OISS_SSA_VEHAUD_SANFIRE_NEW_SIREN_CHARLES", Ref = "OISS_SSA_VEHAUD_SANFIRE_NEW_SOUNDSET"}, --180
--[[181]]  { Name = "New SanFire DAVID",    String = "OISS_SSA_VEHAUD_SANFIRE_NEW_SIREN_DAVID",   Ref = "OISS_SSA_VEHAUD_SANFIRE_NEW_SOUNDSET"}, --181
--[[182]]  { Name = "New SanFire EDWARD",   String = "OISS_SSA_VEHAUD_SANFIRE_NEW_SIREN_EDWARD",  Ref = "OISS_SSA_VEHAUD_SANFIRE_NEW_SOUNDSET"}, --182
--[[183]]  { Name = "Old SanFire HORN",     String = "OISS_SSA_VEHAUD_SANFIRE_OLD_HORN",          Ref = "OISS_SSA_VEHAUD_SANFIRE_OLD_SOUNDSET"}, --183
--[[184]]  { Name = "Old SanFire ADAM",     String = "OISS_SSA_VEHAUD_SANFIRE_OLD_SIREN_ADAM",    Ref = "OISS_SSA_VEHAUD_SANFIRE_OLD_SOUNDSET"}, --184
--[[185]]  { Name = "Old SanFire BOY",      String = "OISS_SSA_VEHAUD_SANFIRE_OLD_SIREN_BOY",     Ref = "OISS_SSA_VEHAUD_SANFIRE_OLD_SOUNDSET"}, --185
--[[186]]  { Name = "Old SanFire CHARLES",  String = "OISS_SSA_VEHAUD_SANFIRE_OLD_SIREN_CHARLES", Ref = "OISS_SSA_VEHAUD_SANFIRE_OLD_SOUNDSET"}, --186
--[[187]]  { Name = "Old SanFire DAVID",    String = "OISS_SSA_VEHAUD_SANFIRE_OLD_SIREN_DAVID",   Ref = "OISS_SSA_VEHAUD_SANFIRE_OLD_SOUNDSET"}, --187
--[[188]]  { Name = "Old SanFire EDWARD",   String = "OISS_SSA_VEHAUD_SANFIRE_OLD_SIREN_EDWARD",  Ref = "OISS_SSA_VEHAUD_SANFIRE_OLD_SOUNDSET"}, --188
--[[189]]  { Name = "New SAMS HORN",        String = "OISS_SSA_VEHAUD_SAMS_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_SAMS_NEW_SOUNDSET"}, --189
--[[190]]  { Name = "New SAMS ADAM",        String = "OISS_SSA_VEHAUD_SAMS_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_SAMS_NEW_SOUNDSET"}, --190
--[[191]]  { Name = "New SAMS BOY",         String = "OISS_SSA_VEHAUD_SAMS_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_SAMS_NEW_SOUNDSET"}, --191
--[[192]]  { Name = "New SAMS CHARLES",     String = "OISS_SSA_VEHAUD_SAMS_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_SAMS_NEW_SOUNDSET"}, --192
--[[193]]  { Name = "New SAMS DAVID",       String = "OISS_SSA_VEHAUD_SAMS_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_SAMS_NEW_SOUNDSET"}, --193
--[[194]]  { Name = "New SAMS EDWARD",      String = "OISS_SSA_VEHAUD_SAMS_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_SAMS_NEW_SOUNDSET"}, --194
--[[195]]  { Name = "Old SAMS HORN",        String = "OISS_SSA_VEHAUD_SAMS_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_SAMS_OLD_SOUNDSET"}, --195
--[[196]]  { Name = "Old SAMS ADAM",        String = "OISS_SSA_VEHAUD_SAMS_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_SAMS_OLD_SOUNDSET"}, --196
--[[197]]  { Name = "Old SAMS BOY",         String = "OISS_SSA_VEHAUD_SAMS_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_SAMS_OLD_SOUNDSET"}, --197
--[[198]]  { Name = "Old SAMS CHARLES",     String = "OISS_SSA_VEHAUD_SAMS_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_SAMS_OLD_SOUNDSET"}, --198
--[[199]]  { Name = "Old SAMS DAVID",       String = "OISS_SSA_VEHAUD_SAMS_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_SAMS_OLD_SOUNDSET"}, --199
--[[200]]  { Name = "Old SAMS EDWARD",      String = "OISS_SSA_VEHAUD_SAMS_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_SAMS_OLD_SOUNDSET"}, --200
--[[201]]  { Name = "USFS HORN",            String = "OISS_SSA_VEHAUD_USFS_NEW_HORN",             Ref = "OISS_SSA_VEHAUD_USFS_NEW_SOUNDSET"}, --201
--[[202]]  { Name = "USFS ADAM",            String = "OISS_SSA_VEHAUD_USFS_NEW_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_USFS_NEW_SOUNDSET"}, --202
--[[203]]  { Name = "USFS BOY",             String = "OISS_SSA_VEHAUD_USFS_NEW_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_USFS_NEW_SOUNDSET"}, --203
--[[204]]  { Name = "USFS CHARLES",         String = "OISS_SSA_VEHAUD_USFS_NEW_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_USFS_NEW_SOUNDSET"}, --204
--[[205]]  { Name = "USFS DAVID",           String = "OISS_SSA_VEHAUD_USFS_NEW_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_USFS_NEW_SOUNDSET"}, --205
--[[206]]  { Name = "USFS EDWARD",          String = "OISS_SSA_VEHAUD_USFS_NEW_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_USFS_NEW_SOUNDSET"}, --206
--[[207]]  { Name = "USFS HORN",            String = "OISS_SSA_VEHAUD_USFS_OLD_HORN",             Ref = "OISS_SSA_VEHAUD_USFS_OLD_SOUNDSET"}, --207
--[[208]]  { Name = "USFS ADAM",            String = "OISS_SSA_VEHAUD_USFS_OLD_SIREN_ADAM",       Ref = "OISS_SSA_VEHAUD_USFS_OLD_SOUNDSET"}, --208
--[[209]]  { Name = "USFS BOY",             String = "OISS_SSA_VEHAUD_USFS_OLD_SIREN_BOY",        Ref = "OISS_SSA_VEHAUD_USFS_OLD_SOUNDSET"}, --209
--[[210]]  { Name = "USFS CHARLES",         String = "OISS_SSA_VEHAUD_USFS_OLD_SIREN_CHARLES",    Ref = "OISS_SSA_VEHAUD_USFS_OLD_SOUNDSET"}, --210
--[[211]]  { Name = "USFS DAVID",           String = "OISS_SSA_VEHAUD_USFS_OLD_SIREN_DAVID",      Ref = "OISS_SSA_VEHAUD_USFS_OLD_SOUNDSET"}, --211
--[[212]]  { Name = "USFS EDWARD",          String = "OISS_SSA_VEHAUD_USFS_OLD_SIREN_EDWARD",     Ref = "OISS_SSA_VEHAUD_USFS_OLD_SOUNDSET"}, --212
--[[213]]  { Name = "Misc. ADAM",           String = "OISS_SSA_VEHAUD_ETC_ADAM",                  Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --213
--[[214]]  { Name = "Misc. BOY",            String = "OISS_SSA_VEHAUD_ETC_BOY",                   Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --214
--[[215]]  { Name = "Misc. CHARLES",        String = "OISS_SSA_VEHAUD_ETC_CHARLES",               Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --215
--[[216]]  { Name = "Misc. DAVID",          String = "OISS_SSA_VEHAUD_ETC_DAVID",                 Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --216
--[[217]]  { Name = "Misc. EDWARD",         String = "OISS_SSA_VEHAUD_ETC_EDWARD",                Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --217
--[[218]]  { Name = "Misc. FRANK",          String = "OISS_SSA_VEHAUD_ETC_FRANK",                 Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --218
--[[219]]  { Name = "Misc. GEORGE",         String = "OISS_SSA_VEHAUD_ETC_GEORGE",                Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --219
--[[220]]  { Name = "Misc. HENRY",          String = "OISS_SSA_VEHAUD_ETC_HENRY",                 Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --220
--[[221]]  { Name = "Misc. IDA",            String = "OISS_SSA_VEHAUD_ETC_IDA",                   Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --221
--[[222]]  { Name = "Misc. JOHN",           String = "OISS_SSA_VEHAUD_ETC_JOHN",                  Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --222
--[[223]]  { Name = "Misc. KING",           String = "OISS_SSA_VEHAUD_ETC_KING",                  Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --223
--[[224]]  { Name = "Misc. LINCOLN",        String = "OISS_SSA_VEHAUD_ETC_LINCOLN",               Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --224
--[[225]]  { Name = "Misc. MARY",           String = "OISS_SSA_VEHAUD_ETC_MARY",                  Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --225
--[[226]]  { Name = "Misc. NANCY",          String = "OISS_SSA_VEHAUD_ETC_NANCY",                 Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --226
--[[227]]  { Name = "Misc. OCEAN",          String = "OISS_SSA_VEHAUD_ETC_OCEAN",                 Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --227
--[[228]]  { Name = "Misc. PAUL",           String = "OISS_SSA_VEHAUD_ETC_PAUL",                  Ref = "OISS_SSA_VEHAUD_ETC_SOUNDSET"}, --228
}
```

{% endcode %}

</details>

<details>

<summary>WM-ServerSiren Example</summary>

[View Raw / View in New Tab](https://pastebin.com/raw/nurDwSDX)

{% code title="SIRENS.lua > SIRENS Table" %}

```lua
SIRENS = {
--[[1]]	  { Name = "Airhorn", 		String = "SIRENS_AIRHORN", 				Ref = 0 }, --1
--[[2]]	  { Name = "Wail", 	        String = "VEHICLES_HORNS_SIREN_1", 			Ref = 0 }, --2
--[[3]]	  { Name = "Yelp", 	        String = "VEHICLES_HORNS_SIREN_2", 			Ref = 0 }, --3
--[[4]]	  { Name = "Priority", 		String = "VEHICLES_HORNS_POLICE_WARNING", 		Ref = 0 }, --4
--[[5]]	  { Name = "Futura", 		String = "RESIDENT_VEHICLES_SIREN_WAIL_01", 		Ref = 0 }, --5
--[[6]]	  { Name = "Hetro", 		String = "RESIDENT_VEHICLES_SIREN_WAIL_02", 		Ref = 0 }, --6
--[[7]]	  { Name = "Sweep-1", 		String = "RESIDENT_VEHICLES_SIREN_WAIL_03", 		Ref = 0 }, --7
--[[8]]	  { Name = "Sweep-2", 		String = "RESIDENT_VEHICLES_SIREN_QUICK_01", 		Ref = 0 }, --8
--[[9]]	  { Name = "Hi-Low",		String = "RESIDENT_VEHICLES_SIREN_QUICK_02",		Ref = 0 }, --9
--[[10]]  { Name = "Whine Down",	String = "RESIDENT_VEHICLES_SIREN_QUICK_03", 		Ref = 0 }, --10
--[[11]]  { Name = "Powercall", 	String = "VEHICLES_HORNS_AMBULANCE_WARNING", 		Ref = 0 }, --11
--[[12]]  { Name = "QSiren", 		String = "VEHICLES_HORNS_FIRETRUCK_WARNING", 		Ref = 0 }, --12
--[[13]]  { Name = "Fire Yelp", 	String = "RESIDENT_VEHICLES_SIREN_FIRETRUCK_WAIL_01", 	Ref = 0 }, --13
--[[14]]  { Name = "Fire Yelp", 	String = "RESIDENT_VEHICLES_SIREN_FIRETRUCK_QUICK_01", 	Ref = 0 }, --14
-- START OF WM-SERVERSIRENS --
--[[15]]  { Name = "Example Tone", 	String = "SIREN_ALPHA", 	Ref = "DLC_WMSIRENS_SOUNDSET" }, --15
--[[16]]  { Name = "Siren Bravo", 	String = "SIREN_BRAVO", 	Ref = "DLC_WMSIRENS_SOUNDSET" }, --16
--[[17]]  { Name = "Custom C", 	        String = "SIREN_CHARLIE", 	Ref = "DLC_WMSIRENS_SOUNDSET" }, --17
--[[18]]  { Name = "Yelp", 	        String = "SIREN_DELTA", 	Ref = "DLC_WMSIRENS_SOUNDSET" }, --18
--[[19]]  { Name = "Priority", 	        String = "SIREN_ECHO", 	        Ref = "DLC_WMSIRENS_SOUNDSET" }, --19
--[[20]]  { Name = "Siren 3", 	        String = "SIREN_FOXTROT", 	Ref = "DLC_WMSIRENS_SOUNDSET" }, --20
--[[21]]  { Name = "Yelp", 	        String = "SIREN_GOLF", 	        Ref = "DLC_WMSIRENS_SOUNDSET" }, --21
--[[22]]  { Name = "Custom H", 	        String = "SIREN_HOTEL", 	Ref = "DLC_WMSIRENS_SOUNDSET" }, --22
}
```

{% endcode %}

</details>

* To replace tones change the **`String`** to the desired siren string `SIREN_XXXX` or `OISS_SSA_XXXX` and the **`Ref`** to `DLC_WMSIRENS_SOUNDSET` or `OISS_SSA_VEHAUD_XXXX`.\
  ⚠️ *This is not recommended. Instead, consider managing the use of default tones by removing them from SIREN\_ASSIGNEMENTS if so desired.*

### Troubleshooting

First, to determine if it is a LVC or AWC issue use the Server Side Audio Tester, follow readme on configuration.

* If it works in SSAT then it is an LVC configuration error, verify your audio banks, strings, and refs for typos.
* If it does not work in SSAT, it is likely your AWC is corrupt, too large, or has a tone that is too large. Try "balancing" tone sizes across multiple AWCs use empty wav files to fill empty tone slots.

{% embed url="<https://github.com/TrevorBarns/Server-Side-Audio-Tester>" %}
Server Side Audio Tester Github
{% endembed %}

### Example Siren Pack

{% embed url="<https://github.com/TrevorBarns/luxart-vehicle-control-extras/tree/master/Siren%20Packs/Server%20Sided%20Packs/Mega%20Pack>" %}
Siren Mega Pack (4 police + 1 Fire Rescue Siren)
{% endembed %}


# FAQ

Frequently asked question about LVC:v3.

## Frequently Asked Questions

* [**Why is this vehicle still using the default profile even after I created a table in SIRENS\_ASSIGNMENTS?**](#why-is-this-vehicle-still-using-the-default-profile-even-after-i-created-a-table-in-sirens_assignmen)
* [**How do I fix "SCRIPT ERROR: @lvc/UTIL/cl\_utils.lua:XX bad argument #1 to 'pairs' (table expected, got nil)"?**](#how-do-i-fix-script-error-lvc-util-cl_utils.lua-xx-bad-argument-1-to-pairs-table-expected-got-nil)

### Why is this vehicle still using the default profile even after I created a table in SIRENS\_ASSIGNMENTS?

The most likely cause for this is the use of an incorrect key in SIRENS\_ASSIGNMENTS. The key in siren assignments needs to align with the vehicles `<gameName>` as found in `vehicles.meta`. The keys first 11 characters also need to be unique due to base game limitations.

To verify this look at these two methods:

* **In game using LVC debug:** Enter the car in question, use command `/lvcdebug` this will display a notification with the gameName and log other useful information to the F8 console.
* **In game using menu**: Enter the car in questions, navigate to 'Storage Management'. The description of the 'Save Profile' button will read "Using DEFAULT profile for "*\<gameName>*". Ensure this matches identically (case-sensitive) to the key as outlined in SIREN\_ASSIGNMENTS.
* **Out of game using `vehicles.meta`**: Locate the `vehicles.meta` file and verify that the vehicle in questions `<gameName>XXXXXXXX</gameName>` = \['XXXXXXXX'] in SIREN\_ASSIGNMENTS.

### How do I fix "SCRIPT ERROR: @lvc/UTIL/cl\_utils.lua:XX bad argument #1 to 'pairs' (table expected, got nil)"?

This indicates that there was a problem loading your SIREN\_ASSIGNMENTS table from your SIRENS.lua.

What causes the table to not be loaded?

* Invalid symbol present:
  * You have accidentally made a typo and left a random symbol somewhere.
  * You pasted text from a website. Typically `RequestScriptAudioBank(“XXX”, false)`. Where the the website uses UTF8 `“` instead of ASCII `"`.
  * You have mismatched curly brackets. For every open bracket `{` there needs to be a closing bracket `}`. Too many of either will result in failure to load. Use a smart text editor like Notepad++ to highlight brackets or an online tool.
* Missing SETTINGS.lua or missing SIREN\_ASSIGNMENTS table in SIRENS.lua


# Introduction to Plugins

Plugins add additional functionality to the base resources for LVC:F and LVCv3.

Plugins are an easy way to add additional functionality Luxart Vehicle Control. Plugins provide the necessary files to run seamlessly with the base resource. The functionality provided in plugins can easily be integrated with the menu if you so decide, but by default are placed in a "Plugins" submenu.

### Current Available Plugins

{% content-ref url="/pages/DpZxcG8mDisBDsG7rynO" %}
[Take-downs](/shared-plugins/take-downs)
{% endcontent-ref %}

{% content-ref url="/pages/Ycv49pLHZcyTnrh1Ykyx" %}
[Extra Controls](/shared-plugins/extra-controls)
{% endcontent-ref %}

{% content-ref url="/pages/fAmug5kEcorUPqbeaLGi" %}
[Extra Integrations](/shared-plugins/extra-integrations)
{% endcontent-ref %}

{% content-ref url="/pages/agbA2aEHuqFs6a7yg5AL" %}
[Traffic Advisor](/shared-plugins/traffic-advisor)
{% endcontent-ref %}

{% content-ref url="/pages/20P8JHvphL82ybmTREHO" %}
[Trailer Support](/shared-plugins/trailer-support)
{% endcontent-ref %}

{% hint style="danger" %}
Plugin-In Support is not yet guaranteed with LVC:Fleet.
{% endhint %}

### Installation

1. Enable plugin support by setting `plugins_installed` to true located in `lvc/SETTINGS.lua`.
2. Copy the desired plugin folder from the release .zip to the PLUGINS folder.
3. Configure the desired plugin to your liking using `/PLUGINS/XXXXX/SETTINGS.lua`. More information can be found on the desired plugins docs page.<br>


# Take-downs

Light up the area in front of your patrol vehicle at the press of a button or by using high-beams.

### Introduction

LVCs first plugin, "takedowns" moves previously implemented take down features to this plugin. The take downs plugin allows clients to activate a bright light in front of their vehicle at the push of a button. The use is to imitate real life take-downs, which are used for illuminating traffic stops and increasing visibility in the dark when attempting to locate persons or things.

It works by using CFX native [DrawSpotlight(...)](https://runtime.fivem.net/doc/natives/?_0xD0F64B265C8C8B33). It does not, modify any extras, but can integrate with your vehicles high-beam system to either trigger on high-beams or trigger high-beams on take-down activation.

### Configuration

1. Ensure that `plugins_installed` is set to true in `/SETTINGS.lua`.
2. Open the SETTINGS.lua located in `/PLUGINS/takedowns`. Adjust settings to your liking.

   <table><thead><tr><th width="285">Variable Name</th><th width="296">Action</th><th align="center">Data Constraints</th><th data-hidden align="center">Common Name</th><th data-hidden align="center">Default</th></tr></thead><tbody><tr><td><code>tkd_masterswitch</code></td><td>Toggles if plugin is enabled. Disabling this removes it from plugin menu, stops it's functionality.</td><td align="center">true / false</td><td align="center">Master-switch</td><td align="center">true</td></tr><tr><td><code>tkd_key</code></td><td>Key that activates take-downs, if tkd_combokey is depressed or disabled.</td><td align="center">Static Control #</td><td align="center">Key</td><td align="center">74</td></tr><tr><td><code>tkd_combokey</code></td><td>Activates tkd_key when depressed if not set to 0.</td><td align="center">Static Control #</td><td align="center">Combokey</td><td align="center">21</td></tr><tr><td><code>tkd_intensity_default</code></td><td>Sets default brightness of take-down light</td><td align="center">0-150</td><td align="center">Default Intensity</td><td align="center">100</td></tr><tr><td><code>tkd_radius_default</code></td><td>Sets default spread angle in reference to vehicle.</td><td align="center">0-90</td><td align="center">Default Radius</td><td align="center">50</td></tr><tr><td><code>tkd_distance_default</code></td><td>Sets default max distance light is visible, brightness effected by fall-off at distance.</td><td align="center">0-250</td><td align="center">Default Distance</td><td align="center">50</td></tr><tr><td><code>tkd_falloff_default</code></td><td>Sets default distance that the light begins to dim due to distance.</td><td align="center">0-2000</td><td align="center">Default Falloff</td><td align="center">1000</td></tr><tr><td><code>tkd_sync_radius</code></td><td>Distance at which take-downs are synced to other users. ⚠️ This has extreme implications on performance, 400 or less is recommended.</td><td align="center">0-10500</td><td align="center">Sync Radius</td><td align="center">400</td></tr><tr><td><code>tkd_highbeam_integration_default</code></td><td>Sets default state for high-beam integration.</td><td align="center">1-3</td><td align="center">Default High-Beam Integration</td><td align="center">2</td></tr></tbody></table>

{% hint style="success" %}
Finished, configure your personal settings in game under in-game 'Plugins->Takedowns' menu.
{% endhint %}


# Extra Controls

Toggle extras on the fly with hotkeys.

## Introduction

The "extra\_controls" plugin handles specific extra toggling on demand using key bindings. The allows players the ability to toggle spotlights, light cuts, scene lights conveniently without navigating through existing menus. Controls can be set by default or left disabled, if `allow_custom_controls` is set to true, players can change each control combo and key in game through an LVC menu.

<figure><img src="https://camo.githubusercontent.com/7fcb8ee3d541d0287bd197a9724976b482db5083de3260cddecd07ec07e8f71b/68747470733a2f2f692e6779617a6f2e636f6d2f32613235336232383539376631373033336364653633656338643937336165332e6a7067" alt=""><figcaption></figcaption></figure>

## Configuration

1. Ensure that `plugins_installed` is set to true in `lvc/SETTINGS.lua`.
2. Open the SETTINGS.lua located in `/plugins/extra_controls`. Adjust settings to your liking.
3. Determine a set of controls/combos that players can use. Configure the EXTRA\_CONTROLS table to your liking.\
   List of Key&#x73;**:** [CFX Game Reference - Controls](https://docs.fivem.net/docs/game-references/controls/)

   *Example:*

   <pre class="language-lua" data-title="SETTINGS.lua"><code class="lang-lua">CONTROLS = {
   	-- COMBOS = { &#x3C;list of index/key ID of approved combo-keys> }, 
   	-- KEYS = { &#x3C;list of index/key ID of approved toggle keys> }
   	COMBOS = { 326, 155, 19, 349 },    --LCTRL, LSHIFT, LALT, TAB
   	KEYS = { 187, 188, 189, 190, 20 }  -- ARROW DWN, UP, LFT, RGT, Z
   }
   </code></pre>
4. Configure the EXTRA\_CONTROLS table to your liking. \
   *Example:*

   <pre class="language-lua" data-title="SETTINGS.lua"><code class="lang-lua">EXTRA_CONTROLS = {
   	['DEFAULT'] = { 	},	
   	['LAPD'] = { 
   			--  	{ '&#x3C;name>', Extras = {&#x3C;extras table>}, Combo = &#x3C;default combo>, Key = &#x3C;default key>, (opt.) Audio = &#x3C; button soundFX> }
   				{ Name = 'Front Cut', Extras = {add = 8, remove = 9, repair = true}, Combo = 155, Key = 20, Audio = true }, 
   				{ Name = 'Scene Lights', Extras = {toggle = 9, repair = true}, Combo = 349, Key = 20, Audio = true }, 
   				{ Name = 'Pass. Spot Light', Extras = {add = 3, remove = 4, repair = true}, Combo = 326, Key = 20, Audio = false }, 
   	},	
   	['so3'] = { 
   			--  	{ '&#x3C;name>', Extras = {&#x3C;extras table>}, Combo = &#x3C;default combo>, Key = &#x3C;default key>, (opt.) Audio = &#x3C; button soundFX> }
   				{ Name = 'Test', Extras = {add = 4, remove = 9, repair = true}, Combo = 155, Key = 20, Audio = true }, 
   				{ Name = 'Test2', Extras = {toggle = 5, repair = true}, Combo = 349, Key = 20, Audio = true }, 
   				{ Name = 'Test3', Extras = {add = 6, remove = 7, repair = true}, Combo = 326, Key = 20, Audio = false }, 
   	},
   }
   </code></pre>

{% hint style="warning" %}
Every default `Combo` and `Key` assignment need to be present at a minimum in the CONTROLS table.
{% endhint %}

### Extras Table

#### **Toggle**

A toggle key will toggle a single extra on trigger or multiple extra if a table is passed in.

* Single Example: \
  `{ Name = 'Test', Extras = { toggle = 4 }, Combo = 155, Key = 20 }`&#x20;
* Multiple Example: \
  `{ Name = 'Test', Extras = {` toggle`= { 4, 5 } }, Combo = 155, Key = 20 }`&#x20;

#### **Add & Remove**

An add and remove key will add the passed extra(s) on trigger and remove passed extras(s) on trigger. When the control is pressed again, the behavior will reverse adding the removed extra(s) and removing the added extra(s).

* Single Example: \
  \``{ Name = 'Test', Extras = { add = 4, remove = 5 }, Combo = 155, Key = 20}`&#x20;
* Multiple Example: \
  `{ Name = 'Cruise', Extras = { add = { 4, 8 }, remove = { 5, 9 }, Combo = 155, Key = 20}`

#### **Repair Flag**

A repair flag can optionally be added for higher poly extras. GTA will set extras of low poly items without repairing the vehicle, however for things like spotlights, lightbars, etc. the repair flag may need to be set. By default `repair` is set to disabled, to override add `repair = true` somewhere inside the desired trigger table.

* Examples:
  * `{ Name = 'Test', Extras = { toggle = 4, repair = true }, Combo = 155, Key = 20 }`
  * `{ Name = 'Cruise', Extras = { add = { 5 }, remove = { 6 }, repair = true }, Combo = 155, Key = 20 }`

#### Controls

* Combo: *combokey* to be pressed in addition to *key* in order to activate profile. `Combo = 0` to disable the need for a combo key.
* Key: *control* to be pressed with *combokey* (if set) in order to activate profile.

#### Audio

The audio flag determines if the plugin plays a button press soundfx (like heard when toggling siren) when the extra\_control profile is toggled.

{% hint style="success" %}
Finished, configure your personal settings in game under 'Plugins->Extra Control' menu.
{% endhint %}


# Extra Integrations

Toggle extras based on vehicle states.

## Introduction

The "extra\_integration" plugin handles specific actions based on vehicles state (braking, accelerating, reversing, stopped, etc.). The primary function is to enable LVC to add / remove vehicle extras based on these states. This allows vehicle developers to map extras to specific vehicle features like light bar brake lights, or rear emergency light reverse override. Future states and extras may be added later.

In addition to toggling extras, this plugin can be used to handle brake light function when stopped, automatically applying brake lights without the control needing to be held.

#### Real-life Examples:

{% embed url="<https://www.youtube.com/watch?v=V-j__JXwqOk>" %}
SoundOff BluePRINT Functionality
{% endembed %}

{% embed url="<https://youtu.be/-Ww6jQxuL2g?t=562>" %}
Whelen Cencom Carbide Functionality
{% endembed %}

### **Currently Supported States/Extras:**

<table><thead><tr><th width="188.33333333333331" align="center">Common Name</th><th width="141">String</th><th width="417.6666666666667">Trigger</th></tr></thead><tbody><tr><td align="center">Brake Lights</td><td><code>Brake</code></td><td>Vehicle is in braking.</td></tr><tr><td align="center">Reverse Lights</td><td><code>Reverse</code></td><td>Vehicle is in reverse.</td></tr><tr><td align="center">Right Indicator</td><td><code>RIndicator</code></td><td>Vehicles left turn signal is active.</td></tr><tr><td align="center">Left Indicator</td><td><code>LIndicator</code></td><td>Vehicles right turn signal is active.</td></tr><tr><td align="center">Takedowns</td><td><code>Takedowns</code></td><td>Take-downs are enabled (requires <em>takedowns</em> plugin).</td></tr><tr><td align="center">Driver Seat</td><td><code>DSeat</code></td><td>Driver seat occupied.</td></tr><tr><td align="center">Driver Door</td><td><code>DDoor</code></td><td>Driver door not latched.</td></tr><tr><td align="center">Passenger Door</td><td><code>PDoor</code></td><td>Passenger door not latched.</td></tr><tr><td align="center">Trunk</td><td><code>Trunk</code></td><td>Trunk is not latched.</td></tr><tr><td align="center">Main Siren</td><td><code>MainSiren</code></td><td>Main/Primary siren is activated.</td></tr><tr><td align="center">Aux Siren</td><td><code>AuxSiren</code></td><td>Aux/Pwrcall siren is activated.</td></tr><tr><td align="center">Air Horn</td><td><code>AirHorn</code></td><td>Air horn is active.</td></tr><tr><td align="center">Manual Tone</td><td><code>Manu</code></td><td>Primary or Secondary Manual tone is active.</td></tr></tbody></table>

### Configuration

1. Ensure that `plugins_installed` is set to true in `lvc/SETTINGS.lua`.
2. Open the SETTINGS.lua located in `/plugins/extra_integration`. Adjust settings to your liking.
3. Now configure the EXTRA\_ASSIGNMENTS table to your liking. The Extra Assignments table is very dynamic an allows for multiple set up variations.\
   *Example:*

   <pre class="language-lua" data-title="SETTINGS.lua"><code class="lang-lua">EXTRA_ASSIGNMENTS = {
       ['LAPD'] = { 
       			--[&#x3C;extra_id>] = { repair = &#x3C;true/false>, toggle = {&#x3C;string(s)>}, reverse = &#x3C;true/false>}
   			[7] = { repair = true, toggle = { "Takedowns", "AirHorn" } },
   			[8] = { repair = true, toggle = { "DSeat" } },
   			[9] = { repair = true, toggle = { "DSeat" } , reverse = true},
   		},
   }
   </code></pre>

   ####

#### Toggle

A toggle key will toggle a single extra on trigger or multiple extra if a table is passed in.

* Single Example: `toggle = { "DSeat" }`
* Multiple Example: `toggle = { "Takedowns", "AirHorn" }`

#### Add & Remove

Add / Remove tables are not currently supported, instead use toggle. Use `reverse` flag to change when state is "active".

#### Repair Flag

A repair flag can optionally be added for higher poly extras. GTA will set extras of low poly items without repairing the vehicle, however for things like spotlights, lightbars, etc. the repair flag may need to be set. By default `repair` is set to disabled, to override add `repair = true` somewhere inside the desired trigger table.

* Examples:
  * `[7] = { repair = true, toggle = { "Takedowns", "AirHorn" } },`
  * `[8] = { repair = true, toggle = { "DSeat" } },`

{% hint style="success" %}
Finished, configure your personal settings in game under 'Plugins->Extra Integrations' menu.
{% endhint %}


# Traffic Advisor

Quickly toggle rear traffic advisor patterns at the press of a button.

## Introduction

The "traffic\_advisor" plugin is designed for extra toggling in order to activate certain rear traffic advisory lights. It works by placing light meshes under certain extras then toggling those extras to reveal or hide certain sirens.

{% hint style="info" %}
**This requires the vehicle to already have working Traffic Advisor extras! LVC does not add a traffic advisor to vehicle which do not already have one.**
{% endhint %}

## Configuration

1. Ensure that `plugins_installed` is set to true in `/SETTINGS.lua`.
2. Open the SETTINGS.lua located in `/plugins/traffic_advisor`. Adjust settings to your liking.
3. Now configure the TA\_ASSIGNMENTS table to your liking. The TA Assignments table is very dynamic an allows for multiple set up variations.\
   *Example:*

   <pre class="language-lua" data-title="SETTINGS.lua"><code class="lang-lua">TA_ASSIGNMENTS = {
     ['DEFAULT'] = { },
     ['gameName'] = { 	lightbar = 3, 
   			left = { on = { add = 8, remove = 7, repair = true }, off = { add = {}, remove = { 7, 8 } } }, 
   			right = { on = { add = 7, remove = 8, repair = true }, off = { add = {}, remove = { 7, 8 } } }, 
   			middle = { on = { add = { 7, 8 }, remove = {}, repair = true }, off = { add = {}, remove = { 7, 8 } } }, 
   		},   
   }
   </code></pre>

#### Lightbar

A lightbar key is used to ensure that the parent extra (a lightbar / TA bar) is present before toggling. This can be disabled by setting equal to '-1' if the TA lightbar is attached to the base model and not an extra.

#### On & Off

An on and off key will be called on TA state change.

#### Add & Remove

An add and remove key will add the passed extra(s) and remove passed extras(s) based on the TAs on/off state.

* Single Example: `on = { add = 1, remove = 2 }`
* Multiple Example: `on = { add = { 1, 3 }, remove = { 2, 4 } }`

{% hint style="info" %}
&#x20;Use `{}` to identify as unneeded. e.g. (`on = { add = 8, remove = {} }`)
{% endhint %}

#### Repair Flag

A repair flag can optionally be added for higher poly extras. GTA will set extras of low poly items without repairing the vehicle, however for things like spotlights, lightbars, etc. the repair flag may need to be set. By default `repair` is set to disabled, to override add `repair = true` somewhere inside the desired trigger table. This should only be needed when *adding* extras.

* Examples:
  * `on = { add = 1, remove = {}, repair = true }`
  * `on = { add = { 5 }, remove = { 6 }, repair = true }`

{% hint style="success" %}
Finished, test your new traffic advisor integration in game.
{% endhint %}


# Trailer Support

Control trailer doors and extras while in the truck towing.

## Introduction

The 'trailer-support' plugin allows more control over trailer attributes such as door position and active extras. It also adds shortcuts which can be used to toggle multiple extras across both the towing vehicle and trailer instantly.

## Configuration

1. Ensure that `plugins_installed` is set to true in `/SETTINGS.lua`.
2. Open the SETTINGS.lua located in `/PLUGINS/trailer_support`.
3. Now configure the TRAILERS table to your liking.

*Example:* 'cfrladtcab' is the cab of a tiller fire truck, aka the tow vehicle.

{% code title="SETTINGS.lua" %}

```lua
TRAILERS = {
        ['<modelName>'] = {
                { "<shortcut name>", { { Trailer = <if the extra is on trailer or tow vehicle>, Extra = <extraId>, State = <state extra should be in when activated> }, { Trailer = < >, extra = < >, State = < > } } },
         },
	['cfrladtcab'] = { 
		{ "Raise Ladder", { { Trailer = false, Extra = 8, State = true }, { Trailer = true, Extra = 2, State = false } } },
		{ "Lower Ladder", { { Trailer = false, Extra = 8, State = false }, { Trailer = true, Extra = 2, State = true } } },
		{ "Open All Doors", { { Trailer = false, Extra = 1, State = false }, { Trailer = true, Extra = 1, State = false } } },
		{ "Close All Doors", { { Trailer = false, Extra = 1, State = true }, { Trailer = true, Extra = 1, State = true } } },
         }
}
```

{% endcode %}

#### Parameters

* **Name:** The first item in a shortcut table is the shortcut name field, this is what will show up as the name of the menu button in game. Try to limit this to a few words as it may otherwise not fit in the menu.
* **Trailer Flag:** The trailer flag is included in each shortcut sub-table and identifies if the extra ID passed is on the trailer or cab/truck.
* **Extra ID:** The extra ID intended to be toggled. This currently only allows a single extra ID, in the future it may allow for more.
* **State:** Should the extra be on or off when toggled. This ensures that regardless of the vehicle spawn state or current extra state LVC will track and toggle extras.

{% hint style="success" %}
Finished, test it out in game under the 'Plugins->Trailer Support' menu.
{% endhint %}


# Resource Installation

Instructions on how to install Pro Laser 4 into your server.

#### Download the latest stable release `Pro.Laser.4.vX.X.X.zip` (not source code) from [releases](https://github.com/TrevorBarns/ProLaser4/releases).

1. **Copy `ProLaser4` to resources folder.**
2. **Add `ensure ProLaser4`to server.cfg.**

If the records tablet is desired continue reading here: [Persistent Records & Tablet](/pro-laser-4/persistent-records-and-tablet)

{% hint style="warning" %}

#### &#x20;Streamed Custom Weapon

It is important to note that **restarting the resource** after players have spawned the weapon **will result in the players FiveM crashing**. If restarting the resource in the future is desired consider moving the weapon related elements (metas and stream folder) to a resource on their own.
{% endhint %}


# Persistent Records & Tablet

How to set up Pro Laser 4 tablet.

### Introduction

By default, Pro Laser 4 will store the last 100 clocks to the player's machine, which will be loaded on player join.&#x20;

The section below describes a centralized database for tracking clocks server side.&#x20;

### Dependencies

[oxmysql](https://github.com/overextended/oxmysql/) - SQL interface resource. Alternatively you can modify `sv_lidar.lua` if you use another resource.

[Documentation for oxmysql](https://overextended.github.io/docs/oxmysql/)

### Setup Pro Laser 4 Database Table

If you do not have an existing database you'd like to use, you can create one, see example below. *Notice:* this must be the same database you connect to in your server.cfg.

**Example:** \
I use a database called `resources` and my connection string looks like this in my server.cfg:&#x20;

{% code overflow="wrap" %}

```bash
set mysql_connection_string "server=localhost;user=<USERNAME>;password=<PASSWORD>;database=resources;charset=utf8mb4;connectTimeout=60000;acquireTimeout=60000;timeout=60000
```

{% endcode %}

{% hint style="warning" %}
During testing, hangs/server crashes occurred when `connectTimeout=60000;acquireTimeout=60000;timeout=60000`\
was not included, your mileage may vary. I would recommend including these just in case.
{% endhint %}

#### Import SQL / Execute&#x20;

Now with your desired database selected you can execute `setup.sql` included with the resource, it will build a table with columns below.

<details>

<summary>Setup SQL Table Command</summary>

```sql
CREATE TABLE `prolaser4` (
	`rid` INT(11) NOT NULL AUTO_INCREMENT,
	`timestamp` DATETIME NOT NULL,
	`speed` INT(11) NOT NULL DEFAULT '0',
	`distance` FLOAT NOT NULL DEFAULT '0',
	`targetX` FLOAT NOT NULL DEFAULT '0',
	`targetY` FLOAT NOT NULL DEFAULT '0',
	`player` TEXT NOT NULL COLLATE 'latin1_swedish_ci',
	`street` TEXT NOT NULL COLLATE 'latin1_swedish_ci',
	`selfTestTimestamp` DATETIME NOT NULL,
	PRIMARY KEY (`rid`) USING BTREE
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=1;
```

</details>

<table><thead><tr><th width="221">Column</th><th width="120.33333333333331">Datatype</th><th>Usage</th></tr></thead><tbody><tr><td><code>rid</code></td><td>INT</td><td>Record ID / Primary Key</td></tr><tr><td><code>timestamp</code></td><td>DATETIME</td><td>Time at which clock occurred.</td></tr><tr><td><code>speed</code></td><td>INT</td><td>Estimated speed from clock.</td></tr><tr><td><code>distance</code></td><td>FLOAT</td><td>Estimated distance from clock.</td></tr><tr><td><code>targetX</code></td><td>FLOAT</td><td>Target entity's GTA X coordinate.</td></tr><tr><td><code>targetY</code></td><td>FLOAT</td><td>Target entity's GTA Y coordinate.</td></tr><tr><td><code>player</code></td><td>TEXT</td><td>Lidar user's name.</td></tr><tr><td><code>street</code></td><td>TEXT</td><td>Street (and cross street if detected) of target vehicles location.</td></tr><tr><td><code>selfTestTimestamp</code></td><td>DATETIME</td><td>Time at which the lidar self-test occurred,<br><code>0000-00-00 00:00:00</code> if self-test disabled in config.</td></tr></tbody></table>

### Logging Configuration

Configure logging settings in `config.lua`. Then use `/lidarrecords` in game to open the tablet and review records.

**Uncomment these two oxmysql lines from fxmanifest:**

<pre class="language-lua"><code class="lang-lua"><strong>...
</strong><strong>dependencies {
</strong><strong>	'oxmysql',		-- uncomment for persistent records &#x26; record management tablet. See docs and configs.
</strong>}
...
server_scripts {
	'@oxmysql/lib/MySQL.lua', -- uncomment for persistent records &#x26; record management tablet. See docs and configs.
<strong>	...
</strong><strong>}
</strong></code></pre>

### Imgur Integration for Record Printing

The Pro Laser 4 can use Imgur as an upload endpoint for "printing" lidar records from the tablet. These are more screenshots than prints but, are roleplayed as such. In order to be able to upload these images to Imgur you will need to generate an API client ID.

1. Navigate to <https://api.imgur.com/oauth2/addclient>
2. Register an application, select "*OAuth 2 authorization without a callback URL*"
3. Navigate to: <https://imgur.com/account/settings/apps>
4. Copy *Client ID* field.
5. Paste in to config in the following format: `cfg.imgurApiKey = 'Client-ID XXXXXXXXXXXXXXX'` where `XXXXXXXXXXXXXXX` is the client ID you copied in step 4.
6. Restart Pro Laser 4 and test out your print functionality in the tablet.

### Discord Webhook for Record Printing

The Pro Laser 4 can also use Discord as an upload endpoint for "printing" lidar records from the tablet. Discord webhook messages include record data and a screenshot of the record document. In order to be able to upload these images to Discord you will need a Discord webhook on a channel.

<div align="center"><figure><img src="https://i.imgur.com/LdYqlaE.png" alt="" width="375"><figcaption><p>Example Embed from PL4</p></figcaption></figure></div>

1. Open "Edit Channel" for the channel where you would like these posted.
2. Navigate to "Integrations" tab.
3. Click "Webhooks", then "New Webhook" if you don't already have one.
4. Then "Copy Webhook URL" and paste in `cfg.discordWebhook`. See example below.
5. Restart Pro Laser 4 and test out your print functionality in the tablet.

{% code title="config.lua" overflow="wrap" fullWidth="false" %}

```lua
cfg.discordWebhook = 'https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXX/YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
```

{% endcode %}

*Note:* customizing the icon or name for the webhook is not necessary, ProLaser4 will set the webhook name and image when posting.


# Font Awesome Icon Configuration

Instructions on configuring Font Awesome to prevent icons from not being shown on Lidar Records Tablet.

### What is Font Awesome?

Font Awesome is a web font and icon provider which allows developers to easily implement intuitive icons into their website.

### Why would I want to proceed with this configuration?

To restore the Lidar Records Tablet icons. Font Awesome offers both paid and free plans. However, free plans are limited by the number of page views and since this is a free resource I will not be paying for page views beyond what the free plan offers.&#x20;

This can result in icons disappearing as my plan's page views exceed the limit. The following steps will help you configure ProLaser4 to use your own account which will reduce the odds of this occurring and help you fix the issue should it occur in the future.

### How to configure Font Awesome & Pro Laser 4

1. Create an account on Font Awesome: <https://fontawesome.com/start>
2. Navigate to "Your Kits": <https://fontawesome.com/kits>
3. Click "Create Your First Kit": <https://fontawesome.com/kits/new>
4. Select the "Free Styles" icon kits.\
   ![](/files/q0mg8t1vjCnFQ8pV6zBT)
5. Select Next.
6. Select "Hosted by Us".
7. You do not need to provide a domain, select Next.
8. Enter a name for the kit.
9. Select "Make My Kit".
10. Copy the unique kit token provided on the next page. \
    ![](/files/qj9J1jhkDT0O9YfmQz1W)
11. Open `ProLaser4\UI\html\index.html`
12. Paste the unique code overriding the default on line 13.\
    ![](/files/jWmcCnj5I627jm6DraSS)
13. Restart ProLaser4.

\
After following these steps you should have icons in your Lidar Records Tablet, you may need to refresh this token based on how large your server is, and how many "page views" your server uses.<br>


# In Game Use Guide

Instructions on how to use Pro Laser 4 in game.

### Open Lidar Display:

1. Spawn / Equip Pro Laser 4 Weapon.
2. Use `/lidar` or press `cfg.toggleMenu` control to open lidar display.

### **Controls:**

<table><thead><tr><th width="198" align="center">Key</th><th width="374.3333333333333">Description</th><th align="center">Type</th></tr></thead><tbody><tr><td align="center"><code>I</code></td><td>Toggle lidar display.</td><td align="center">Modifiable in FiveM Settings</td></tr><tr><td align="center"><code>C</code></td><td>Change sniper vs. simulated sight display in 1st person.</td><td align="center">Static</td></tr><tr><td align="center"><code>LEFT MOUSE</code></td><td>Clock target speed player is aimed at.</td><td align="center">Static</td></tr><tr><td align="center"><code>RIGHT MOUSE</code></td><td>Toggle aim.</td><td align="center">Static</td></tr><tr><td align="center"><code>RIGHT ARROW</code></td><td>Open history and scroll next, hold to fast scroll.</td><td align="center">Static</td></tr><tr><td align="center"><code>LEFT ARROW</code></td><td>Close history and scroll previous, hold to fast scroll.</td><td align="center">Static</td></tr><tr><td align="center"><code>SCROLLWHEEL UP</code></td><td>Zooms in.</td><td align="center">Static</td></tr><tr><td align="center"><code>SCROLLWHEEL DWN</code></td><td>Zooms out.</td><td align="center">Static</td></tr></tbody></table>

### Commands:

`/lidar` same as `I` key, toggles lidar display.

`/lidarwipe` clears lidar history save data.

`/lidarweapon` adds Pro Laser 4 weapon to ped.

`/lidarmove` to move and resize the on screen display.

`/lidarmove true` to reset on screen display size and location to defaults.

**If logging is enabled & configured:**\
`/lidarrecords` opens records tablet to view previous clock data.

### Interface Guide

<figure><img src="https://lh5.googleusercontent.com/IKc4RDxnGnMk7fPz1V__YQdSN_Cb4L88x0K69px-3UFAgnv3QTRAkRyySe9L7LzuolK95gWqCzn9ifgbJbidzkj_tpXYeHNkX9JvdVcKVCPgOP97VGDMM9c8sJSpbi46LrUfA6SU0We5wbeM0A-jLzQ" alt=""><figcaption><p>Speed - Range Display / Home</p></figcaption></figure>

<figure><img src="https://lh4.googleusercontent.com/xlTeQDr_DUWn166S4Ov9nThJ0ggKg6QOBPNDZNMHWVEx-XxdYprHvbanQS8PSdvNGYWLdwUFisgEDlmDFIj1T1h5YljIXYukGJ3Z3HXugdNGGSjQbINqQ7wxyDLJCaNPxCrrsoNv859Zx4R-HuPwokI" alt=""><figcaption><p>Recalled Events / History</p></figcaption></figure>

<figure><img src="https://lh6.googleusercontent.com/PbnKGAKESHEaPK5-rB9-x7gfCNsaBXxUg-1OkQ0wv-CYRvRDlyMTNUTMhTYoRTWqiknjlbi0pH9BEuLt_lrnVuxrAfKl464ntwEoB1z5CBTDN9l6pCTucCUodUbw8uRb2fwHJo4hTyO5Af30Ku44lrI" alt=""><figcaption><p>Reticle / Sight Display</p></figcaption></figure>

### Range, Heading, and Entity Type Limitation

The lidar gun can clock AI vehicles up to your view distance (1100-1800 ft max.). Civilian vehicles clock range is limited by FiveM’s OneSync to 400-500 ft. It also has no built-in entity type limitations, it can clock vehicles, bicycles, peds, animals, and aircraft.&#x20;

**Cosine Error**

An effect when lidar gun (and therefore beam) and target are not perpendicular to each other. The larger the angle between the instrument and the target the larger the error in clocking a vehicle speed. This error results in an *underestimation* of the vehicles speed, meaning the display will show a speed less than that of the actual target speed. While we can't actually measure the tangent or simulate the lidar beam, it is a rough estimation based on heading. The reduction also has a random scalar, to help simulate the different surfaces the beam may be hitting each with a different tangent.

It is important for players to be trained on this and understand the effects of Cosine error. The image below describes the mathematical relationship. You can read more at the link below.

<figure><img src="https://i.imgur.com/LDrXoGu.png" alt=""><figcaption><p>Credit: <a href="https://copradar.com/chapts/chapt2/ch2d1.html">copradar.com/chapts/chapt2/ch2d1.html</a></p></figcaption></figure>

<figure><img src="https://i.imgur.com/G2qleWz.png" alt=""><figcaption><p>Credit: <a href="https://copradar.com/chapts/chapt2/ch2d1.html">copradar.com/chapts/chapt2/ch2d1.html</a></p></figcaption></figure>

{% embed url="<https://copradar.com/chapts/chapt2/ch2d1.html>" %}

### In Vehicle Angle Limits

While in vehicles, you are only able to clock vehicles within 110 degrees right and 178 degrees left, simulating inability to shoot through the rear windows. There are also camera limits when aimed in first person, against these limits causes the screen to jitter as the resource forces your camera back into allowable angles. The camera may also clip against the interior of the vehicle, this is expected and there isn’t really a solution.

In the future this will be expanded to support passenger seat angles: [Product Roadmaps](/product-roadmaps)

<figure><img src="/files/dfRTxGQSNDnEFoIHewkY" alt=""><figcaption><p>Angle Limitation In-Vehicle</p></figcaption></figure>

### Calibration / Self-Test Behavior

If `cfg.requireCalibration` is set to true in config upon opening the lidar display or aiming down HUD sight for the first time the lidar will perform a self-test for 3 to 13 seconds. It will display a progress bar and a self-test timer. After calibration the lidar will display an empty speed-range layout.

### Recalled Events Menu

Every entity clocked will be added to the recalled events menu. If the clocked entity is the same as the last entity AND the new speed is higher than the stored speed in the recalled event table then the save data will be overridden to reflect new speed, range, and time.

<pre class="language-javascript" data-title="Update Pseudocode"><code class="lang-javascript"><strong>If (lastVeh == currVeh AND lastVehSpeed &#x3C; currVehSpeed){
</strong>    // update existing data to new speed, range, and time
}
</code></pre>

The recalled events menu can be navigated by pressing or holding `LEFT ARROW` or `RIGHT ARROW`. Holding either of these for 5 seconds will “fast-scroll” through the events. To close the recalled events menu navigate to the 1st record indicated by 1 in the top left corner and hit `LEFT ARROW` again. Recalled event data is saved every minute (if new data is present) and loaded on join.

### Records Tablet

If [Persistent Records & Tablet](/pro-laser-4/persistent-records-and-tablet) has been setup, then players in-game can review all players past clocks in accordance with logging settings in `config.lua`. The records tablet is a simulated tablet/laptop application that can retrieve all players previous clocks. It also allows printing clock data which includes information about the lidar gun, it's self-test state, and more.

Users clocks are submitted to the server every minute, if any are pending. All records waiting server side are inserted to the database every 5 minutes. As such, **the records tablet can have a delay of up to 6 minutes by default,** however this can be changed in the config under `cfg.loggingInsertInterval`**.**

<figure><img src="/files/qQPWF6bObgcyd9WRNEzP" alt=""><figcaption><p>Records Tablet Main Screen</p></figcaption></figure>

<figure><img src="/files/701MA7hMMFC2457xw749" alt=""><figcaption><p>Print Preview</p></figcaption></figure>

<figure><img src="/files/4dZPOPAmOowxF1sntjdJ" alt=""><figcaption><p>Print To Image</p></figcaption></figure>


# Framework Guide

Additional information for configuring Pro Laser 4 with frameworks.

### QB-Core

**Weapon**

Create a new weapon for Pro Laser 4 with attributes in \
`qb-core/shared/weapons.lua`

{% code title="weapons.lua" %}

```lua
[`weapon_prolaser4`] = { 
    ['name'] = 'weapon_prolaser4',
    ['label'] = 'Lidar Gun',
    ['ammotype'] = 'nil',
    ['damagereason'] = 'Ticketed / Fined / Caught Speeding / Slow Down'
},
```

{% endcode %}

**Item**

Create a new item for Pro Laser 4 with attributes in \
`qb-core/shared/items.lua`

{% code title="items.lua" %}

```lua
['weapon_prolaser4'] = {
    ['name'] = 'weapon_prolaser4',
    ['label'] = 'Lidar Gun',
    ['weight'] = 1000,
    ['type'] = 'weapon',
    ['ammotype'] = 'nil',
    ['image'] = 'weapon_prolaser4.png',
    ['unique'] = true,
    ['useable'] = false,
    ['description'] = 'ProLaser4 Lidar Gun'
},
```

{% endcode %}

### Overextended

Create a new item for Pro Laser 4 with attributes in \
`ox_invetory/weapons.lua`

{% code title="weapons.lua" %}

```lua
['WEAPON_PROLASER4'] = {
	label = 'Lidar Gun',
	weight = 700,
	durability = 0.1,
},
```

{% endcode %}

### Sample Weapon Icons

<div><figure><img src="/files/vZ9DFA6so05CHxYljJwA" alt=""><figcaption><p>Small</p></figcaption></figure> <figure><img src="/files/gdDb6BR9MaC3f0wSY2at" alt=""><figcaption><p>Small Brighter</p></figcaption></figure> <figure><img src="/files/wtcx2bbkuGlIAiSLcDYY" alt=""><figcaption><p>Large</p></figcaption></figure> <figure><img src="/files/TCYQJUgchb7FodgcZ0pQ" alt=""><figcaption><p>Large<br>Brighter</p></figcaption></figure></div>


