<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=CrosRoad95</id>
	<title>Multi Theft Auto: Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multitheftauto.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=CrosRoad95"/>
	<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/wiki/Special:Contributions/CrosRoad95"/>
	<updated>2026-05-18T10:19:35Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.3</generator>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=XmlLoadString&amp;diff=81442</id>
		<title>XmlLoadString</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=XmlLoadString&amp;diff=81442"/>
		<updated>2024-12-01T10:31:23Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
{{New feature/item|3.0158|1.5.7|19626|This function creates an [[Xmlnode]] from a string input.}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
xmlnode xmlLoadString ( string xmlString )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{OOP|This function is a static function underneath the XML class.|[[XML]].loadstring||}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''xmlString:''' A string containing XML data&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns the root [[xmlnode]] object of an xml string if successful, or ''false'' otherwise (invalid XML string).&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example loads an XML string and loops the children while outputting to debugscript.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local rootNode = xmlLoadString(&amp;quot;&amp;lt;animals test='x'&amp;gt;&amp;lt;monkey name='dutchman'&amp;gt;&amp;lt;/monkey&amp;gt; &amp;lt;fox name='luxy'&amp;gt;&amp;lt;/fox&amp;gt;&amp;lt;/animals&amp;gt;&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
if rootNode then&lt;br /&gt;
	local rootAttributes = xmlNodeGetAttributes(rootNode)&lt;br /&gt;
	print(&amp;quot;Root Node&amp;quot;, &amp;quot;Name: &amp;quot;..xmlNodeGetName(rootNode),  &amp;quot;Attributes :&amp;quot;..toJSON(rootAttributes))&lt;br /&gt;
	&lt;br /&gt;
	local children = xmlNodeGetChildren(rootNode)&lt;br /&gt;
	&lt;br /&gt;
	for i, childNode in ipairs(children) do&lt;br /&gt;
		local attributes = xmlNodeGetAttributes(childNode)&lt;br /&gt;
		print(&amp;quot;Child #&amp;quot;..i, &amp;quot;Name: &amp;quot;..xmlNodeGetName(childNode), &amp;quot;Attributes :&amp;quot;..toJSON(attributes))&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Shared xml functions}}&lt;br /&gt;
[[ru:xmlLoadString]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=FileGetContents&amp;diff=80819</id>
		<title>FileGetContents</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=FileGetContents&amp;diff=80819"/>
		<updated>2024-10-19T05:24:15Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|21938|&lt;br /&gt;
Reads the entire contents of the file, optionally verifies the read contents by computing and comparing the checksum with the expected one, and returns the content as string. The file cursor position is not modified by calls to this function. File must be added in the [[meta.xml]].&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Please note that even if you enable SD #22 and #23 on your server, you are not protected from user attacks, which can happen after verification of the file, but before you read the contents of such verified file. This function enables you to safely read the contents of a meta.xml-listed file on both client and server.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
nil|string fileGetContents ( file theFile [ , bool verifyContents = true ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[file]]:getContents}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''theFile:''' A handle to the file you wish to get the contents from. Use [[fileOpen]] to obtain this handle.&lt;br /&gt;
*'''verifyContents:''' Set to true, to compare the computed and the expected checksum of the file content. &lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns the bytes that were read from the file, but only if verification was disabled or if the checksum comparison succeeded. On failure, this function returns ''nil''.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example opens the code.lua file, checks its contents, and then runs it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local handle = fileOpen(&amp;quot;code.lua&amp;quot;, true)&lt;br /&gt;
local buffer = fileGetContents(handle) -- code.lua must be listed in meta.xml (for example as &amp;lt;file&amp;gt; for this example)&lt;br /&gt;
fileClose(handle)&lt;br /&gt;
&lt;br /&gt;
if buffer then&lt;br /&gt;
    loadstring(buffer)() -- This is just an example. You should avoid using loadstring. If you are dealing with configuration use json functions instead for security reasons.&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{File functions}}&lt;br /&gt;
[[pt-br:fileGetContents]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Slipe&amp;diff=80607</id>
		<title>Slipe</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Slipe&amp;diff=80607"/>
		<updated>2024-09-29T06:01:21Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;&amp;lt;big&amp;gt;&amp;lt;big&amp;gt;Native C# for MTA&amp;lt;/big&amp;gt;&amp;lt;/big&amp;gt;  With Slipe Server you're able to run a Native C# MTA server. Making use of the entire dotnet ecosytem, any NuGet package you want, industry-standard ORMs and logging frameworks, and far more.  Slipe Server enables you to make use of the full power of C#. This includes but is not limited to: type safety, inheritance, multithreading and async/await.   See more at: https://server.mta-slipe.com/  Get started at: https://github.com/mta...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;big&amp;gt;&amp;lt;big&amp;gt;Native C# for MTA&amp;lt;/big&amp;gt;&amp;lt;/big&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With Slipe Server you're able to run a Native C# MTA server. Making use of the entire dotnet ecosytem, any NuGet package you want, industry-standard ORMs and logging frameworks, and far more.&lt;br /&gt;
&lt;br /&gt;
Slipe Server enables you to make use of the full power of C#. This includes but is not limited to: type safety, inheritance, multithreading and async/await.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See more at: https://server.mta-slipe.com/&lt;br /&gt;
&lt;br /&gt;
Get started at: https://github.com/mta-slipe/Slipe-Server&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=ExecuteBrowserJavascript&amp;diff=79774</id>
		<title>ExecuteBrowserJavascript</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=ExecuteBrowserJavascript&amp;diff=79774"/>
		<updated>2024-07-05T19:16:43Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: removed vulnerability from example :) because i want to backdoor everyone&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Client function}}&lt;br /&gt;
{{New feature/item|3.0150|1.5||&lt;br /&gt;
This function executes a Javascript string to the specified [[Element/Browser|browser]]. Works only with local browsers.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool executeBrowserJavascript ( browser webBrowser, string jsCode )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{{OOP||[[Element/Browser|browser]]:executeJavascript}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''webBrowser:''' The web browser which will execute the Javascript code&lt;br /&gt;
*'''jsCode:''' The Javascript code string&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if executing Javascript is allowed in the current context, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example shows how to display the name (nick) of the local player on the webpage.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local browser = guiGetBrowser(guiCreateBrowser(200, 200, 400, 200, true, false, false))&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onClientBrowserCreated&amp;quot;, browser,&lt;br /&gt;
    function ()&lt;br /&gt;
        loadBrowserURL(source, &amp;quot;http://mta/local/example.html&amp;quot;) --Containing &amp;lt;span id=&amp;quot;nick&amp;quot;&amp;gt;&amp;lt;/span&amp;gt; somewhere in the file&lt;br /&gt;
    end)&lt;br /&gt;
&lt;br /&gt;
--The page has to load first&lt;br /&gt;
addEventHandler(&amp;quot;onClientBrowserDocumentReady&amp;quot;, browser,&lt;br /&gt;
    function ()&lt;br /&gt;
        executeBrowserJavascript(source, string.format(&amp;quot;document.getElementById('nick').innerText = %q;&amp;quot;, getPlayerName(localPlayer)))&lt;br /&gt;
    end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{CEF_functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:executeBrowserJavascript]]&lt;br /&gt;
[[RO:executeBrowserJavascript]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=79478</id>
		<title>Script security</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=79478"/>
		<updated>2024-05-31T18:59:16Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Securing setElementData */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Awareness of client memory==&lt;br /&gt;
&lt;br /&gt;
Starting from very basics:&lt;br /&gt;
* You should be aware that everything you store on client-side is at risk, this includes Lua itself. Any confidential (and/or) important data could be accessed by malicious clients.&lt;br /&gt;
* To keep sensitive data (and/or) Lua logic safe - use server-side.&lt;br /&gt;
* Do note that scripts marked as '''shared''' act also as '''client code''', which means that everything above applies to them. For example defining:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;shared&amp;quot;/&amp;gt; &amp;lt;!-- this script will run separately both on client and server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Is same as doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;client&amp;quot;/&amp;gt; &amp;lt;!-- define it separately on client --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;server&amp;quot;/&amp;gt; &amp;lt;!-- do the same, but on server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Additional protection layer==&lt;br /&gt;
&lt;br /&gt;
In order to make things ''slightly harder*'' for those having bad intentions towards your server, you can make use of cache attribute (and/or [https://luac.mtasa.com/ Lua compile (also known as Luac) with extra obfuscation set to level '''3'''] - [https://wiki.multitheftauto.com/wiki/Lua_compilation_API API]) available in [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml], along with configuring MTA's built-in AC by toggling SD (Special detections), see: [https://wiki.multitheftauto.com/wiki/Anti-cheat_guide Anti-cheat guide].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;shared.lua&amp;quot; type=&amp;quot;shared&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;client.lua&amp;quot; type=&amp;quot;client&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Slightly harder'' '''but not impossible''' for some to obtain client code, yet does good job at keeping '''most''' people away from inspecting your .lua files - those looking for possible logic flaws (bugs) or missing/incorrect security based checks.&lt;br /&gt;
* Can be used on both '''client''' and '''shared''' script type (has no effect on server-sided Lua).&lt;br /&gt;
* It doesn't remove Lua files which were previously downloaded.&lt;br /&gt;
&lt;br /&gt;
==Detecting and dealing with backdoors and cheats==&lt;br /&gt;
'''To ensure minimum (or no) damage resulting from Lua scripts:'''&lt;br /&gt;
* Keep your server up-to-date, you can [https://nightly.multitheftauto.com/ download latest server builds from MTA:SA nightly site.] Information on specific builds can be [https://buildinfo.multitheftauto.com/ found here.]&lt;br /&gt;
* Keep your resources up-to-date, you can [https://github.com/multitheftauto/mtasa-resources download latest (default) resources from GitHub repository.] Those often contain latest security fixes, which could mean difference between having your server resist from attack or not.&lt;br /&gt;
* Make sure to properly configure [https://wiki.multitheftauto.com/wiki/Access%20Control%20List ACL (Access Control List)] - which will block resources from using certain, potentially dangerous functions.&lt;br /&gt;
* Zero-trust with giving away admin rights for resources (including maps) coming from unknown sources.&lt;br /&gt;
* Before running any resource you don't trust, analyze:&lt;br /&gt;
** [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml] of it, for possible hidden scripts lurking beneath other file extensions.&lt;br /&gt;
** It's source code, for malicious logic.&lt;br /&gt;
* Do not run/keep using compiled resources (scripts) of which legitimacy you aren't sure.&lt;br /&gt;
&lt;br /&gt;
'''To ensure minimum damage when a cheater connects to your server:'''&lt;br /&gt;
* When making scripts, remember to never trust data coming from a client.&lt;br /&gt;
* While reviewing scripts for possible security holes. Look at any data coming from the client that is being trusted.&lt;br /&gt;
* Any kind of data could be sent, hence server scripts which communicate with client by receiving data sent by players should validate it, before further use in latter parts of code. Mostly, it will be done either by [[setElementData]] or [[triggerServerEvent]].&lt;br /&gt;
* You shouldn't rely only on player [https://wiki.multitheftauto.com/wiki/Serial serial], when it comes to processing crucial operations (auto-login/admin actions). '''Serials aren't guaranted to be unique or non-fakable'''. This is why you should '''put it behind''' account system, as '''important authentication factor''' (e.g: '''login &amp;amp; password''').&lt;br /&gt;
* Server-side logic '''can not be bypassed''' or '''tampered''' with (unless server is breached or when there is a bug in code, but that's whole different scenario) - '''use it to your advantage'''. In majority of cases, you will be able to perform security validations with no participation of client-side.&lt;br /&gt;
* Using concept of '''''“All parameters including source can be faked and should not be trusted. Global variable client can be trusted.”''''' - gives you reliable assurance that player to which you refer (via '''client''') '''is''' in fact, '''the one which really called event'''. This approach will protect you from situations where cheater can call (and process) admin events (e.g kick/ban player) by passing the actual admin ('''2nd''' argument in '''[[triggerServerEvent]]''') - as a consequence of using wrong variable. To make sure you fully understood it, take a look at examples below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	DON'T EVER DO THAT - THAT IS COMPLETELY WRONG AND INSECURE&lt;br /&gt;
	THE ISSUE: BY USING 'source' IN hasObjectPermissionTo YOU ARE LEAVING DOOR STRAIGHT OPEN FOR CHEATERS&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerWrongAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(source, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- the vulnerability lies here...&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerWrongAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerWrongAdminEvent&amp;quot;, root, onServerWrongAdminEvent)&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	onServerCorrectAdminEvent IS PERFECTLY SECURED, AS IT SHOULD BE&lt;br /&gt;
	NO ISSUE HERE: WE'VE USED 'client' IN hasObjectPermissionTo WHICH MAKES IT SAFE FROM FAKING PLAYER WHO CALLED EVENT&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerCorrectAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(client, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- is player allowed to do that?&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerCorrectAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerCorrectAdminEvent&amp;quot;, root, onServerCorrectAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing setElementData==&lt;br /&gt;
&lt;br /&gt;
* Don't use setElementData, send to client only necessary data using triggerClientEvent only when needed.&lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of basic element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = tostring(sourceElement) -- element which received data&lt;br /&gt;
	local logOldValue = tostring(oldValue) -- old value&lt;br /&gt;
	local logNewValue = tostring(newValue) -- new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;=======================================\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;=======================================&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local logVisibleTo = root -- specify who will see this log in console, in this case each player connected to server&lt;br /&gt;
	local hadData = (oldValue ~= nil) -- check if element had such data before&lt;br /&gt;
&lt;br /&gt;
	if (hadData) then -- if element had such data before&lt;br /&gt;
		setElementData(sourceElement, dataKey, oldValue) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
	else&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it completely&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	outputConsole(logText, logVisibleTo) -- print it to console&lt;br /&gt;
&lt;br /&gt;
	return true -- all success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeBasicAC(dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not go further&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkSpecialThing = (dataKey == &amp;quot;special_thing&amp;quot;) -- compare whether dataKey matches &amp;quot;special_thing&amp;quot;&lt;br /&gt;
	local checkFlagWaving = (dataKey == &amp;quot;flag_waving&amp;quot;) -- compare whether dataKey matches &amp;quot;flag_waving&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if (checkSpecialThing) then -- if it does, do our security checks&lt;br /&gt;
		local invalidElement = (client ~= source) -- verify whether source element is different from player which changed data&lt;br /&gt;
&lt;br /&gt;
		if (invalidElement) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;special_thing&amp;quot; can only be set for player himself&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkFlagWaving) then -- if it does, do our security checks&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(client) -- get player's current vehicle&lt;br /&gt;
		local invalidVehicle = (playerVehicle ~= source) -- verify whether source element is different from player's vehicle&lt;br /&gt;
&lt;br /&gt;
		if (invalidVehicle) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;flag_waving&amp;quot; can only be set for player's own vehicle&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeBasicAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of comfortable advanced element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan, allowOnlyProtectedKeys to true (as per default configuration)&lt;br /&gt;
	If allowOnlyProtectedKeys is enabled, do not forget to add every client-side element data key to protectedKeys table - otherwise you will face false-positives&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (handleDataChange) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	[&amp;quot;keyName&amp;quot;] = { -- name of key which would be protected&lt;br /&gt;
		onlyForPlayerHimself = true, -- enabling this (true) will make sure that this element data key can only be set on player who synced it (ignores onlyForOwnPlayerVeh and allowForElements), use false/nil to disable this&lt;br /&gt;
		onlyForOwnPlayerVeh = false, -- enabling this (true) will make sure that this element data key can only be set on player's current vehicle who synced it (ignores allowForElements), use false/nil to disable this&lt;br /&gt;
		allowForElements = { -- restrict this key for certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
			[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = { -- restrict this key for certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 32}, -- if value is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
		allowedTableLength = {1, 64}, -- if value is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
		allowedNumberRange = {1, 128}, -- if value is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
	}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering element data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local allowOnlyProtectedKeys = true -- disallow (remove by using removeElementData, if it didn't existed before) every element data besides those given in protectedKeys table; in case someone wanted to flood server with garbage keys, which would be kept in memory until server restart or manual remove - setElementData(source, key, nil) won't remove it; it has to be removeElementData&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
local protectedKeys = {&lt;br /&gt;
	[&amp;quot;vehicleNumber&amp;quot;] = { -- we want vehicleNumber to be set only on vehicles, with stricte numbers in range of 1-100&lt;br /&gt;
		allowForElements = {&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedNumberRange = {1, 100},&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;personalVehData&amp;quot;] = { -- we want be able to set personalVehData only on current vehicle, also it should be a string with length between 1-24&lt;br /&gt;
		onlyForOwnPlayerVeh = true,&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 24},&lt;br /&gt;
	},&lt;br /&gt;
	-- perform security checks on keys stored in this table, in a convenient way&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of element which received data&lt;br /&gt;
	local logOldValue = inspect(oldValue) -- in-depth view of old value&lt;br /&gt;
	local logNewValue = inspect(newValue) -- in-depth view of new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Fail reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (forceRemove) then -- we don't want this element data key to exist at all&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it&lt;br /&gt;
&lt;br /&gt;
		return true -- return success and stop here, we don't need further checks&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	setElementData(sourceElement, dataKey, oldValue) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
&lt;br /&gt;
	return true -- return success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function handleDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from protectedKeys), false otherwise&lt;br /&gt;
	local protectedKey = protectedKeys[dataKey] -- look up whether key changed is stored in protectedKeys table&lt;br /&gt;
&lt;br /&gt;
	if (not protectedKey) then -- if it's not&lt;br /&gt;
&lt;br /&gt;
		if (allowOnlyProtectedKeys) then -- if we don't want garbage keys&lt;br /&gt;
			local failReason = &amp;quot;Key isn't present in protectedKeys&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = true -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return true -- this key isn't protected, let it through&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local onlyForPlayerHimself = protectedKey.onlyForPlayerHimself -- if key has &amp;quot;self-set&amp;quot; lock&lt;br /&gt;
	local onlyForOwnPlayerVeh = protectedKey.onlyForOwnPlayerVeh -- if key has &amp;quot;self-vehicle&amp;quot; lock&lt;br /&gt;
	local allowForElements = protectedKey.allowForElements -- if key has element type check&lt;br /&gt;
	local allowedDataTypes = protectedKey.allowedDataTypes -- if key has allowed data type check&lt;br /&gt;
&lt;br /&gt;
	if (onlyForPlayerHimself) then -- if &amp;quot;self-set&amp;quot; lock is active&lt;br /&gt;
		local matchingElement = (clientElement == sourceElement) -- verify whether player who set data is equal to element which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElement) then -- if it's not matching&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player himself&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (onlyForOwnPlayerVeh) then -- if &amp;quot;self-vehicle&amp;quot; lock is active&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(clientElement) -- get current vehicle of player which set data&lt;br /&gt;
		local matchingVehicle = (playerVehicle == sourceElement) -- check whether it matches the one which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingVehicle) then -- if it doesn't match&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player's own vehicle&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowForElements) then -- check if it's one of them&lt;br /&gt;
		local elementType = getElementType(sourceElement) -- get type of element whose data changed&lt;br /&gt;
		local matchingElementType = allowForElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElementType) then -- this isn't matching&lt;br /&gt;
			local failReason = &amp;quot;Invalid element type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowedDataTypes) then -- if there's allowed data types&lt;br /&gt;
		local valueType = type(newValue) -- get data type of value&lt;br /&gt;
		local matchingType = allowedDataTypes[valueType] -- check if it's one of allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingType) then -- if it's not then&lt;br /&gt;
			local failReason = &amp;quot;Invalid data type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedStringLength = protectedKey.allowedStringLength -- if key has specified string length check&lt;br /&gt;
		local dataString = (valueType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
		if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
			local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
			local stringLength = utf8.len(newValue) -- get length of data string&lt;br /&gt;
			local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedTableLength = protectedKey.allowedTableLength -- if key has table length check&lt;br /&gt;
		local dataTable = (valueType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
		if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
			local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
			local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
			local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
			local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
			for _, _ in pairs(newValue) do -- loop through whole table&lt;br /&gt;
				tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
				minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
				maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
				if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
					break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
				local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedNumberRange = protectedKey.allowedNumberRange -- if key has allowed number range check&lt;br /&gt;
		local dataNumber = (valueType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
		if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
			local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
			local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
			local matchingRange = (newValue &amp;gt;= minRange) and (newValue &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingRange) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this data key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeAdvancedAC(dataKey, oldValue, newValue) -- this event makes use of handleDataChange, the code was split for better readability&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not continue&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedChange = handleDataChange(client, source, dataKey, oldValue, newValue) -- run our security checks&lt;br /&gt;
&lt;br /&gt;
	if (approvedChange) then -- it's all cool and good&lt;br /&gt;
		return false -- we don't need further action&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(client, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(client, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeAdvancedAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing triggerServerEvent==&lt;br /&gt;
&lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player (client) '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of comfortable anti-cheat function designed for events, used for data validation for both normal, and admin events which are called from client-side.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan to true (as per default configuration)&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (processServerEventData) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	checkACLGroup = { -- check whether player who called event belongs to at least one group below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;Admin&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkPermissions = { -- check whether player who called event has permission to at least one thing below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;function.kickPlayer&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkEventData = {&lt;br /&gt;
		{&lt;br /&gt;
			debugData = &amp;quot;source&amp;quot;, -- optional details for report shown in debug message&lt;br /&gt;
			eventData = source, -- data we want to verify&lt;br /&gt;
			equalTo = client, -- compare whether eventData == equalTo&lt;br /&gt;
			allowedElements = { -- restrict eventData to be certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
				[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedDataTypes = { -- restrict eventData to be certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
				[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedStringLength = {1, 32}, -- if eventData is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
			allowedTableLength = {1, 64}, -- if eventData is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
			allowedNumberRange = {1, 128}, -- if eventData is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering server event data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
function processServerEventData(clientElement, sourceElement, serverEvent, securityChecks) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from securityChecks), false otherwise&lt;br /&gt;
	if (not securityChecks) then -- if we haven't passed any security checks&lt;br /&gt;
		return true -- nothing to check, let code go further&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (not clientElement) then -- if client variable isn't available for some reason (although it should never happen)&lt;br /&gt;
		local failReason = &amp;quot;Client variable not present&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkACLGroup = securityChecks.checkACLGroup -- if there's any ACL groups to check&lt;br /&gt;
	local checkPermissions = securityChecks.checkPermissions -- if there's any permissions to check&lt;br /&gt;
	local checkEventData = securityChecks.checkEventData -- if there's any data checks&lt;br /&gt;
&lt;br /&gt;
	if (checkACLGroup) then -- let's check player ACL groups&lt;br /&gt;
		local playerAccount = getPlayerAccount(clientElement) -- get current account of player&lt;br /&gt;
		local guestAccount = isGuestAccount(playerAccount) -- if account is guest (meaning player is not logged in)&lt;br /&gt;
&lt;br /&gt;
		if (guestAccount) then -- it's the case&lt;br /&gt;
			local failReason = &amp;quot;Can't retrieve player login - guest account&amp;quot; -- reason shown in report&lt;br /&gt;
			local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
			reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local accountName = getAccountName(playerAccount) -- get name of player's current account&lt;br /&gt;
		local aclString = &amp;quot;user.&amp;quot;..accountName -- format it for further use in isObjectInACLGroup function&lt;br /&gt;
&lt;br /&gt;
		for groupID = 1, #checkACLGroup do -- iterate over table of given groups&lt;br /&gt;
			local groupName = checkACLGroup[groupID] -- get each group name&lt;br /&gt;
			local aclGroup = aclGetGroup(groupName) -- check if such group exists&lt;br /&gt;
&lt;br /&gt;
			if (not aclGroup) then -- it doesn't&lt;br /&gt;
				local failReason = &amp;quot;ACL group '&amp;quot;..groupName..&amp;quot;' is missing&amp;quot; -- reason shown in report&lt;br /&gt;
				local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
				reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local playerInACLGroup = isObjectInACLGroup(aclString, aclGroup) -- check if player belong to the group&lt;br /&gt;
&lt;br /&gt;
			if (playerInACLGroup) then -- yep, it's the case&lt;br /&gt;
				return true -- so it's a success&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Player doesn't belong to any given ACL group&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkPermissions) then -- check if player has at least one desired permission&lt;br /&gt;
		local allowedByDefault = false -- does he have access by default&lt;br /&gt;
&lt;br /&gt;
		for permissionID = 1, #checkPermissions do -- iterate over all permissions&lt;br /&gt;
			local permissionName = checkPermissions[permissionID] -- get permission name&lt;br /&gt;
			local hasPermission = hasObjectPermissionTo(clientElement, permissionName, allowedByDefault) -- check whether player is allowed to perform certain action&lt;br /&gt;
&lt;br /&gt;
			if (hasPermission) then -- if player has access&lt;br /&gt;
				return true -- one is available (and enough), server won't bother to check others (as return keywords also breaks loop)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Not enough permissions&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkEventData) then -- if there is some data to verify&lt;br /&gt;
&lt;br /&gt;
		for dataID = 1, #checkEventData do -- iterate over each of data&lt;br /&gt;
			local dataToCheck = checkEventData[dataID] -- get each data set&lt;br /&gt;
			local eventData = dataToCheck.eventData -- this is the one we'll be verifying&lt;br /&gt;
			local equalTo = dataToCheck.equalTo -- we want to compare whether eventData == equalTo&lt;br /&gt;
			local allowedElements = dataToCheck.allowedElements -- check whether is element, and whether belongs to certain element types&lt;br /&gt;
			local allowedDataTypes = dataToCheck.allowedDataTypes -- do we restrict data to be certain type?&lt;br /&gt;
			local debugData = dataToCheck.debugData -- additional helper data&lt;br /&gt;
			local debugText = debugData and &amp;quot; (&amp;quot;..debugData..&amp;quot;)&amp;quot; or &amp;quot;&amp;quot; -- if it's present, format it nicely&lt;br /&gt;
&lt;br /&gt;
			if (equalTo) then -- equal check exists&lt;br /&gt;
				local matchingData = (eventData == equalTo) -- compare whether those two values are equal&lt;br /&gt;
&lt;br /&gt;
				if (not matchingData) then -- they aren't&lt;br /&gt;
					local failReason = &amp;quot;Data isn't equal @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedElements) then -- we do check whether is an element, and belongs to at least one given in the list&lt;br /&gt;
				local validElement = isElement(eventData) -- check if it's actual element&lt;br /&gt;
&lt;br /&gt;
				if (not validElement) then -- it's not&lt;br /&gt;
					local failReason = &amp;quot;Data isn't element @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local elementType = getElementType(eventData) -- it's element, so we want to know it's type&lt;br /&gt;
				local matchingElementType = allowedElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingElementType) then -- it's not allowed&lt;br /&gt;
					local failReason = &amp;quot;Invalid element type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedDataTypes) then -- let's check allowed data types&lt;br /&gt;
				local dataType = type(eventData) -- get data type&lt;br /&gt;
				local matchingType = allowedDataTypes[dataType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingType) then -- it isn't&lt;br /&gt;
					local failReason = &amp;quot;Invalid data type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedStringLength = dataToCheck.allowedStringLength -- if data has string length check&lt;br /&gt;
				local dataString = (dataType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
				if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
					local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
					local stringLength = utf8.len(eventData) -- get length of data string&lt;br /&gt;
					local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedTableLength = dataToCheck.allowedTableLength -- if data has table length check&lt;br /&gt;
				local dataTable = (dataType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
				if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
					local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
					local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
					local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
					local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
					for _, _ in pairs(eventData) do -- loop through whole table&lt;br /&gt;
						tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
						minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
						maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
						if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
							break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
						local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedNumberRange = dataToCheck.allowedNumberRange -- if data has number range check&lt;br /&gt;
				local dataNumber = (dataType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
				if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
					local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
					local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
					local matchingRange = (eventData &amp;gt;= minRange) and (eventData &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingRange) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this event call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- helper function to log and handle accidents&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view player which called event&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of source element&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected event abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Event: &amp;quot;..serverEvent..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect or skipPunishment) then -- we don't want to punish player for some reason&lt;br /&gt;
		return true -- stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(clientElement, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(clientElement, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- all done, report success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onServerEvent(clientData)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local dataToPass = 10&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerEvent&amp;quot;, localPlayer, dataToPass)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = clientData, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;number&amp;quot;] = true, -- we want it to be only number&lt;br /&gt;
					},&lt;br /&gt;
					allowedNumberRange = {1, 100}, -- in range of 1 to 100&lt;br /&gt;
					debugData = &amp;quot;clientData&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerEvent&amp;quot;, root, onServerEvent)&lt;br /&gt;
&lt;br /&gt;
function onServerAdminEvent(playerToBan)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server admin event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local playerToBan = getPlayerFromName(&amp;quot;playerToBan&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerAdminEvent&amp;quot;, localPlayer, playerToBan)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerAdminEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkACLGroup = { -- we need to check whether player who called event belongs to ACL groups&lt;br /&gt;
				&amp;quot;Admin&amp;quot;, -- in this case admin group&lt;br /&gt;
			},&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = playerToBan, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;player&amp;quot;] = true, -- we want it to be player&lt;br /&gt;
					},&lt;br /&gt;
					debugData = &amp;quot;playerToBan&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerAdminEvent&amp;quot;, root, onServerAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing server-only events==&lt;br /&gt;
* It is very important to '''disable remote triggering''' ability in [https://wiki.multitheftauto.com/wiki/AddEvent addEvent], to prevent calling server-side only events from client-side.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example shows how you should make event server-side only.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onServerSideOnlyEvent()&lt;br /&gt;
	-- do some server-side stuff&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerSideOnlyEvent&amp;quot;, false) -- set second argument (allowRemoteTriger) to false, so it can't be called from client&lt;br /&gt;
addEventHandler(&amp;quot;onServerSideOnlyEvent&amp;quot;, root, onServerSideOnlyEvent) -- associate our event with function onServerSideOnlyEvent&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing projectiles &amp;amp; explosions==&lt;br /&gt;
This section (and '''code''' is '''work in progress''') - '''use at your own risk'''.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile ammo tracker:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerProjectileAmmo = {} -- store player-held weapons ammo here&lt;br /&gt;
local playerWeaponsToTrack = { -- keep track of ammo for certain player-held weapon types, basically those which create projectile; [weaponID] = weaponSlot&lt;br /&gt;
	[16] = 8, -- grenade&lt;br /&gt;
	[17] = 8, -- teargas&lt;br /&gt;
	[18] = 8, -- molotov&lt;br /&gt;
	[35] = 7, -- rocket launcher&lt;br /&gt;
	[36] = 7, -- rocket launcher (heat-seeking)&lt;br /&gt;
	[39] = 8, -- satchel charge&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for weaponID, weaponSlot in pairs(playerWeaponsToTrack) do&lt;br /&gt;
		local weaponInSlot = getPedWeapon(playerElement, weaponSlot)&lt;br /&gt;
		local weaponTotalAmmo = getPedTotalAmmo(playerElement, weaponSlot)&lt;br /&gt;
		local weaponHasAmmo = (weaponTotalAmmo &amp;gt; 0)&lt;br /&gt;
		local weaponMatching = (weaponInSlot == weaponID)&lt;br /&gt;
		local updateWeaponAmmo = (weaponMatching and weaponHasAmmo)&lt;br /&gt;
&lt;br /&gt;
		if (updateWeaponAmmo) then&lt;br /&gt;
			local storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			local newWeaponAmmo = (updateWeaponAmmo and weaponTotalAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
			if (not storedProjectileAmmo) then&lt;br /&gt;
				playerProjectileAmmo[playerElement] = {}&lt;br /&gt;
				storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			storedProjectileAmmo[weaponID] = newWeaponAmmo&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function hasPlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
	local projectileAmmo = (projectileData and projectileData[projectileWeapon])&lt;br /&gt;
&lt;br /&gt;
	return projectileAmmo&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectileData) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileWeaponAmmo = playerProjectileData[projectileWeapon]&lt;br /&gt;
	local tempProjectileAmmo = (projectileWeaponAmmo - 1)&lt;br /&gt;
	local newProjectileAmmo = (tempProjectileAmmo &amp;gt; 0 and tempProjectileAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectileData[projectileWeapon] = newProjectileAmmo&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerWeaponSwitchAntiCheat(previousWeaponID, currentWeaponID)&lt;br /&gt;
	setTimer(updateProjectileAmmoForPlayer, 50, 1, source)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWeaponSwitch&amp;quot;, root, onPlayerWeaponSwitchAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onResourceStartAntiCheat()&lt;br /&gt;
	local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	for playerID = 1, #playersTable do&lt;br /&gt;
		local playerElement = playersTable[playerID]&lt;br /&gt;
&lt;br /&gt;
		updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, resourceRoot, onResourceStartAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerWastedQuitAntiCheat()&lt;br /&gt;
	playerProjectileAmmo[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWasted&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerCreatedProjectiles = {} -- store count of legitimately created player projectiles; [playerElement] = {[projectileType] = activeProjectiles}&lt;br /&gt;
local projectileTypes = {&lt;br /&gt;
	[16] = { -- Grenade&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[17] = { -- Teargas&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[17] = true, -- teargas&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[18] = { -- Molotov&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[19] = { -- Rocket&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[425] = true, -- hunter&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[20] = { -- Rocket (heat-seeking)&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[21] = { -- Airbomb&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[39] = { -- Satchel charge&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[39] = true, -- satchel charge&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[58] = { -- Hydra flare&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportProjectileAbnormality(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	local projectileSyncer = inspect(playerElement)&lt;br /&gt;
	local projectilePosition = (projectileX..&amp;quot;, &amp;quot;..projectileY..&amp;quot;, &amp;quot;..projectileZ)&lt;br /&gt;
	local projectileZoneName = getZoneName(projectileX, projectileY, projectileZ, false)&lt;br /&gt;
	local projectileCityName = getZoneName(projectileX, projectileY, projectileZ, true)&lt;br /&gt;
	local projectileLog =&lt;br /&gt;
		&amp;quot;* Detected projectile abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile syncer: &amp;quot;..projectileSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile type: &amp;quot;..projectileType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile position: &amp;quot;..projectilePosition.. &amp;quot; (&amp;quot;..projectileZoneName..&amp;quot;, &amp;quot;..projectileCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(projectileLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processProjectileChecks(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
	local projectileAllowed = projectileData.projectileAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not projectileAllowed) then&lt;br /&gt;
		return false, &amp;quot;Projectile not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileAllowedWeapons = projectileData.projectileAllowedWeapons&lt;br /&gt;
&lt;br /&gt;
	if (projectileAllowedWeapons) then&lt;br /&gt;
		local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
		local allowedWeapon = projectileAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedWeapon) then&lt;br /&gt;
			return false, &amp;quot;Player is not holding correct weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
		local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
		if (not playerHasAmmo) then&lt;br /&gt;
			return false, &amp;quot;Player doesn't have ammo for weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerVehicle) then&lt;br /&gt;
		local projectileAllowedVehicles = projectileData.projectileAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
		if (projectileAllowedVehicles) then&lt;br /&gt;
			local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
			local allowedVehicle = projectileAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedVehicle) then&lt;br /&gt;
				return false, &amp;quot;Player is not inside allowed vehicles&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
			local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
			if (not playerDriver) then&lt;br /&gt;
				return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Player in vehicle&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxDistanceFromCreator = projectileData.projectileMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToProjectile = getDistanceBetweenPoints3D(playerX, playerY, playerZ, projectileX, projectileY, projectileZ)&lt;br /&gt;
		local matchingProjectileDistance = (distanceToProjectile &amp;lt;= projectileMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileDistance) then&lt;br /&gt;
			return false, &amp;quot;Projectile distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxVelocity = projectileData.projectileMaxVelocity&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxVelocity) then&lt;br /&gt;
		local projectileVelocity = (projectileVX ^ 2 + projectileVY ^ 2 + projectileVZ ^ 2)&lt;br /&gt;
		local projectileSpeed = math.sqrt(projectileVelocity)&lt;br /&gt;
		local matchingProjectileVelocity = (projectileSpeed &amp;lt;= projectileMaxVelocity)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileVelocity) then&lt;br /&gt;
			return false, &amp;quot;Projectile velocity mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function trackPlayerProjectile(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		playerCreatedProjectiles[playerElement] = {}&lt;br /&gt;
		playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID] or 0&lt;br /&gt;
	local newProjectilesCount = (projectilesByType + 1)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
&lt;br /&gt;
	if (not projectileData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileBehaviour = projectileData.projectileOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not projectileBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = projectileBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = projectileBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = projectileBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID]&lt;br /&gt;
&lt;br /&gt;
	if (not projectilesByType) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local tempProjectilesCount = (projectilesByType - 1)&lt;br /&gt;
	local newProjectilesCount = (tempProjectilesCount &amp;gt; 0 and tempProjectilesCount or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerProjectileCreationAntiCheat(projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local approvedProjectile, detectionCode = processProjectileChecks(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedProjectile) then&lt;br /&gt;
		trackPlayerProjectile(source, projectileType)&lt;br /&gt;
&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportProjectileAbnormality(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerProjectileCreation&amp;quot;, root, onPlayerProjectileCreationAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerQuitAntiCheat()&lt;br /&gt;
	playerCreatedProjectiles[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Explosions handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local rocketInstantExplosionDistanceThreshold = 1.55 -- distance below which only explosion will be created (and not rocket projectile, hence not calling onPlayerProjectileCreation); do not change it&lt;br /&gt;
local explosionTypes = { -- more specific info on explosion, and whether it is allowed&lt;br /&gt;
	[0] = { -- Grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[1] = { -- Molotov&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[2] = { -- Rocket&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[3] = { -- Rocket weak&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[4] = { -- Car&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[5] = { -- Car quick&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[6] = { -- Boat&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[7] = { -- Heli&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[8] = { -- Mine&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[9] = { -- Object&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[10] = { -- Tank grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionMaxDistanceFromCreator = 80,&lt;br /&gt;
		explosionAllowedVehicles = {&lt;br /&gt;
			[432] = true,&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	[11] = { -- Small&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[12] = { -- Tiny&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportExplosionAbnormality(playerElement, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	local explosionSyncer = inspect(playerElement)&lt;br /&gt;
	local explosionType = explosionType&lt;br /&gt;
	local explosionPosition = (explosionX..&amp;quot;, &amp;quot;..explosionY..&amp;quot;, &amp;quot;..explosionZ)&lt;br /&gt;
	local explosionZoneName = getZoneName(explosionX, explosionY, explosionZ, false)&lt;br /&gt;
	local explosionCityName = getZoneName(explosionX, explosionY, explosionZ, true)&lt;br /&gt;
	local explosionLog =&lt;br /&gt;
		&amp;quot;* Detected explosion abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion syncer: &amp;quot;..explosionSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion type: &amp;quot;..explosionType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion position: &amp;quot;..explosionPosition.. &amp;quot; (&amp;quot;..explosionZoneName..&amp;quot;, &amp;quot;..explosionCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(explosionLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processExplosionChecks(playerElement, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
	local explosionAllowed = explosionData.explosionAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not explosionAllowed) then&lt;br /&gt;
		return false, &amp;quot;Explosion type not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local rocketExplosion = (explosionType == 2)&lt;br /&gt;
&lt;br /&gt;
	if (rocketExplosion) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local instantExplosion = (distanceToExplosion &amp;lt; rocketInstantExplosionDistanceThreshold)&lt;br /&gt;
&lt;br /&gt;
		if (instantExplosion) then&lt;br /&gt;
			local explosionAllowedWeapons = explosionData.explosionAllowedWeapons&lt;br /&gt;
			local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
			local allowedWeapon = explosionAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedWeapon) then&lt;br /&gt;
				return false, &amp;quot;Player is not holding rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
			local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
			if (not playerHasAmmo) then&lt;br /&gt;
				return false, &amp;quot;Player doesn't have ammo for rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedProjectiles = explosionData.explosionAllowedProjectiles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedProjectiles) then&lt;br /&gt;
&lt;br /&gt;
		for projectileID, _ in pairs(explosionAllowedProjectiles) do&lt;br /&gt;
			local atleastOneProjectile = decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
&lt;br /&gt;
			if (atleastOneProjectile) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Explosion created without respective projectile&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedVehicles = explosionData.explosionAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedVehicles) then&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
		if (not playerVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is not in vehicle&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
		local allowedVehicle = explosionAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is inside not allowed vehicles&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
		local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
		if (not playerDriver) then&lt;br /&gt;
			return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionMaxDistanceFromCreator = explosionData.explosionMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (explosionMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local matchingExplosionDistance = (distanceToExplosion &amp;lt; explosionMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingExplosionDistance) then&lt;br /&gt;
			return false, &amp;quot;Explosion distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
&lt;br /&gt;
	if (not explosionData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionBehaviour = explosionData.explosionOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not explosionBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = explosionBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = explosionBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = explosionBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onExplosionAntiCheat(explosionX, explosionY, explosionZ, explosionType)&lt;br /&gt;
	local serverSyncExplosion = (source == root)&lt;br /&gt;
&lt;br /&gt;
	if (serverSyncExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedExplosion, detectionCode = processExplosionChecks(source, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportExplosionAbnormality(source, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onExplosion&amp;quot;, root, onExplosionAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handling non-registered events==&lt;br /&gt;
&lt;br /&gt;
See: [[onPlayerTriggerInvalidEvent]]&lt;br /&gt;
&lt;br /&gt;
==Handling events spam==&lt;br /&gt;
See: [[onPlayerTriggerEventThreshold]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=79477</id>
		<title>Script security</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Script_security&amp;diff=79477"/>
		<updated>2024-05-31T18:58:52Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Securing setElementData */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Awareness of client memory==&lt;br /&gt;
&lt;br /&gt;
Starting from very basics:&lt;br /&gt;
* You should be aware that everything you store on client-side is at risk, this includes Lua itself. Any confidential (and/or) important data could be accessed by malicious clients.&lt;br /&gt;
* To keep sensitive data (and/or) Lua logic safe - use server-side.&lt;br /&gt;
* Do note that scripts marked as '''shared''' act also as '''client code''', which means that everything above applies to them. For example defining:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;shared&amp;quot;/&amp;gt; &amp;lt;!-- this script will run separately both on client and server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Is same as doing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;client&amp;quot;/&amp;gt; &amp;lt;!-- define it separately on client --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;script.lua&amp;quot; type=&amp;quot;server&amp;quot;/&amp;gt; &amp;lt;!-- do the same, but on server --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Additional protection layer==&lt;br /&gt;
&lt;br /&gt;
In order to make things ''slightly harder*'' for those having bad intentions towards your server, you can make use of cache attribute (and/or [https://luac.mtasa.com/ Lua compile (also known as Luac) with extra obfuscation set to level '''3'''] - [https://wiki.multitheftauto.com/wiki/Lua_compilation_API API]) available in [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml], along with configuring MTA's built-in AC by toggling SD (Special detections), see: [https://wiki.multitheftauto.com/wiki/Anti-cheat_guide Anti-cheat guide].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;shared.lua&amp;quot; type=&amp;quot;shared&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;client.lua&amp;quot; type=&amp;quot;client&amp;quot; cache=&amp;quot;false&amp;quot;/&amp;gt; &amp;lt;!-- cache=&amp;quot;false&amp;quot; indicates that this Lua file won't be saved on player's PC --&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* ''Slightly harder'' '''but not impossible''' for some to obtain client code, yet does good job at keeping '''most''' people away from inspecting your .lua files - those looking for possible logic flaws (bugs) or missing/incorrect security based checks.&lt;br /&gt;
* Can be used on both '''client''' and '''shared''' script type (has no effect on server-sided Lua).&lt;br /&gt;
* It doesn't remove Lua files which were previously downloaded.&lt;br /&gt;
&lt;br /&gt;
==Detecting and dealing with backdoors and cheats==&lt;br /&gt;
'''To ensure minimum (or no) damage resulting from Lua scripts:'''&lt;br /&gt;
* Keep your server up-to-date, you can [https://nightly.multitheftauto.com/ download latest server builds from MTA:SA nightly site.] Information on specific builds can be [https://buildinfo.multitheftauto.com/ found here.]&lt;br /&gt;
* Keep your resources up-to-date, you can [https://github.com/multitheftauto/mtasa-resources download latest (default) resources from GitHub repository.] Those often contain latest security fixes, which could mean difference between having your server resist from attack or not.&lt;br /&gt;
* Make sure to properly configure [https://wiki.multitheftauto.com/wiki/Access%20Control%20List ACL (Access Control List)] - which will block resources from using certain, potentially dangerous functions.&lt;br /&gt;
* Zero-trust with giving away admin rights for resources (including maps) coming from unknown sources.&lt;br /&gt;
* Before running any resource you don't trust, analyze:&lt;br /&gt;
** [https://wiki.multitheftauto.com/wiki/Meta.xml meta.xml] of it, for possible hidden scripts lurking beneath other file extensions.&lt;br /&gt;
** It's source code, for malicious logic.&lt;br /&gt;
* Do not run/keep using compiled resources (scripts) of which legitimacy you aren't sure.&lt;br /&gt;
&lt;br /&gt;
'''To ensure minimum damage when a cheater connects to your server:'''&lt;br /&gt;
* When making scripts, remember to never trust data coming from a client.&lt;br /&gt;
* While reviewing scripts for possible security holes. Look at any data coming from the client that is being trusted.&lt;br /&gt;
* Any kind of data could be sent, hence server scripts which communicate with client by receiving data sent by players should validate it, before further use in latter parts of code. Mostly, it will be done either by [[setElementData]] or [[triggerServerEvent]].&lt;br /&gt;
* You shouldn't rely only on player [https://wiki.multitheftauto.com/wiki/Serial serial], when it comes to processing crucial operations (auto-login/admin actions). '''Serials aren't guaranted to be unique or non-fakable'''. This is why you should '''put it behind''' account system, as '''important authentication factor''' (e.g: '''login &amp;amp; password''').&lt;br /&gt;
* Server-side logic '''can not be bypassed''' or '''tampered''' with (unless server is breached or when there is a bug in code, but that's whole different scenario) - '''use it to your advantage'''. In majority of cases, you will be able to perform security validations with no participation of client-side.&lt;br /&gt;
* Using concept of '''''“All parameters including source can be faked and should not be trusted. Global variable client can be trusted.”''''' - gives you reliable assurance that player to which you refer (via '''client''') '''is''' in fact, '''the one which really called event'''. This approach will protect you from situations where cheater can call (and process) admin events (e.g kick/ban player) by passing the actual admin ('''2nd''' argument in '''[[triggerServerEvent]]''') - as a consequence of using wrong variable. To make sure you fully understood it, take a look at examples below:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	DON'T EVER DO THAT - THAT IS COMPLETELY WRONG AND INSECURE&lt;br /&gt;
	THE ISSUE: BY USING 'source' IN hasObjectPermissionTo YOU ARE LEAVING DOOR STRAIGHT OPEN FOR CHEATERS&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerWrongAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(source, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- the vulnerability lies here...&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerWrongAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerWrongAdminEvent&amp;quot;, root, onServerWrongAdminEvent)&lt;br /&gt;
&lt;br /&gt;
--[[&lt;br /&gt;
	onServerCorrectAdminEvent IS PERFECTLY SECURED, AS IT SHOULD BE&lt;br /&gt;
	NO ISSUE HERE: WE'VE USED 'client' IN hasObjectPermissionTo WHICH MAKES IT SAFE FROM FAKING PLAYER WHO CALLED EVENT&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function onServerCorrectAdminEvent(playerToBan)&lt;br /&gt;
	if (not client) then -- 'client' points to the player who triggered the event, and should be used as security measure (in order to prevent player faking)&lt;br /&gt;
		return false -- if this variable doesn't exists at the moment (for unknown reason, or it was the server who triggered this event), stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local defaultPermission = false -- do not allow action by default, see (defaultPermission): https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo&lt;br /&gt;
	local canAdminBanPlayer = hasObjectPermissionTo(client, &amp;quot;function.banPlayer&amp;quot;, defaultPermission) -- is player allowed to do that?&lt;br /&gt;
&lt;br /&gt;
	if (not canAdminBanPlayer) then -- if player doesn't have permissions&lt;br /&gt;
		return false -- don't do it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local validElement = isElement(playerToBan) -- check whether argument passed from client is an element&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then -- it is not&lt;br /&gt;
		return false -- stop code processing&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local elementType = getElementType(playerToBan) -- it's an element, so get it's type&lt;br /&gt;
	local playerType = (elementType == &amp;quot;player&amp;quot;) -- make sure that it's a player&lt;br /&gt;
&lt;br /&gt;
	if (not playerType) then -- it's not a player&lt;br /&gt;
		return false -- stop here&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- banPlayer(...) -- do what needs to be done&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerCorrectAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerCorrectAdminEvent&amp;quot;, root, onServerCorrectAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing setElementData==&lt;br /&gt;
&lt;br /&gt;
* 1. Don't use setElementData, send to client only necessary data using triggerClientEvent only when needed.&lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of basic element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = tostring(sourceElement) -- element which received data&lt;br /&gt;
	local logOldValue = tostring(oldValue) -- old value&lt;br /&gt;
	local logNewValue = tostring(newValue) -- new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;=======================================\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;=======================================&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	local logVisibleTo = root -- specify who will see this log in console, in this case each player connected to server&lt;br /&gt;
	local hadData = (oldValue ~= nil) -- check if element had such data before&lt;br /&gt;
&lt;br /&gt;
	if (hadData) then -- if element had such data before&lt;br /&gt;
		setElementData(sourceElement, dataKey, oldValue) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
	else&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it completely&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	outputConsole(logText, logVisibleTo) -- print it to console&lt;br /&gt;
&lt;br /&gt;
	return true -- all success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeBasicAC(dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not go further&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkSpecialThing = (dataKey == &amp;quot;special_thing&amp;quot;) -- compare whether dataKey matches &amp;quot;special_thing&amp;quot;&lt;br /&gt;
	local checkFlagWaving = (dataKey == &amp;quot;flag_waving&amp;quot;) -- compare whether dataKey matches &amp;quot;flag_waving&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	if (checkSpecialThing) then -- if it does, do our security checks&lt;br /&gt;
		local invalidElement = (client ~= source) -- verify whether source element is different from player which changed data&lt;br /&gt;
&lt;br /&gt;
		if (invalidElement) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;special_thing&amp;quot; can only be set for player himself&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkFlagWaving) then -- if it does, do our security checks&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(client) -- get player's current vehicle&lt;br /&gt;
		local invalidVehicle = (playerVehicle ~= source) -- verify whether source element is different from player's vehicle&lt;br /&gt;
&lt;br /&gt;
		if (invalidVehicle) then -- if it's so&lt;br /&gt;
			reportAndRevertDataChange(client, source, dataKey, oldValue, newValue) -- revert data change, because &amp;quot;flag_waving&amp;quot; can only be set for player's own vehicle&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeBasicAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of comfortable advanced element data anti-cheat.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan, allowOnlyProtectedKeys to true (as per default configuration)&lt;br /&gt;
	If allowOnlyProtectedKeys is enabled, do not forget to add every client-side element data key to protectedKeys table - otherwise you will face false-positives&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (handleDataChange) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	[&amp;quot;keyName&amp;quot;] = { -- name of key which would be protected&lt;br /&gt;
		onlyForPlayerHimself = true, -- enabling this (true) will make sure that this element data key can only be set on player who synced it (ignores onlyForOwnPlayerVeh and allowForElements), use false/nil to disable this&lt;br /&gt;
		onlyForOwnPlayerVeh = false, -- enabling this (true) will make sure that this element data key can only be set on player's current vehicle who synced it (ignores allowForElements), use false/nil to disable this&lt;br /&gt;
		allowForElements = { -- restrict this key for certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
			[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = { -- restrict this key for certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
			[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 32}, -- if value is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
		allowedTableLength = {1, 64}, -- if value is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
		allowedNumberRange = {1, 128}, -- if value is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
	}&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering element data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local allowOnlyProtectedKeys = true -- disallow (remove by using removeElementData, if it didn't existed before) every element data besides those given in protectedKeys table; in case someone wanted to flood server with garbage keys, which would be kept in memory until server restart or manual remove - setElementData(source, key, nil) won't remove it; it has to be removeElementData&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
local protectedKeys = {&lt;br /&gt;
	[&amp;quot;vehicleNumber&amp;quot;] = { -- we want vehicleNumber to be set only on vehicles, with stricte numbers in range of 1-100&lt;br /&gt;
		allowForElements = {&lt;br /&gt;
			[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedNumberRange = {1, 100},&lt;br /&gt;
	},&lt;br /&gt;
	[&amp;quot;personalVehData&amp;quot;] = { -- we want be able to set personalVehData only on current vehicle, also it should be a string with length between 1-24&lt;br /&gt;
		onlyForOwnPlayerVeh = true,&lt;br /&gt;
		allowedDataTypes = {&lt;br /&gt;
			[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
		},&lt;br /&gt;
		allowedStringLength = {1, 24},&lt;br /&gt;
	},&lt;br /&gt;
	-- perform security checks on keys stored in this table, in a convenient way&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- helper function to log and revert changes&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view of player which forced element data sync&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of element which received data&lt;br /&gt;
	local logOldValue = inspect(oldValue) -- in-depth view of old value&lt;br /&gt;
	local logNewValue = inspect(newValue) -- in-depth view of new value&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected element data abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Data key: &amp;quot;..dataKey..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Old data value: &amp;quot;..logOldValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;New data value: &amp;quot;..logNewValue..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Fail reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (forceRemove) then -- we don't want this element data key to exist at all&lt;br /&gt;
		removeElementData(sourceElement, dataKey) -- remove it&lt;br /&gt;
&lt;br /&gt;
		return true -- return success and stop here, we don't need further checks&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	setElementData(sourceElement, dataKey, oldValue) -- revert changes, it will call onElementDataChange event, but will fail (stop) on first condition - because server (not client) forced change&lt;br /&gt;
&lt;br /&gt;
	return true -- return success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function handleDataChange(clientElement, sourceElement, dataKey, oldValue, newValue) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from protectedKeys), false otherwise&lt;br /&gt;
	local protectedKey = protectedKeys[dataKey] -- look up whether key changed is stored in protectedKeys table&lt;br /&gt;
&lt;br /&gt;
	if (not protectedKey) then -- if it's not&lt;br /&gt;
&lt;br /&gt;
		if (allowOnlyProtectedKeys) then -- if we don't want garbage keys&lt;br /&gt;
			local failReason = &amp;quot;Key isn't present in protectedKeys&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = true -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return true -- this key isn't protected, let it through&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local onlyForPlayerHimself = protectedKey.onlyForPlayerHimself -- if key has &amp;quot;self-set&amp;quot; lock&lt;br /&gt;
	local onlyForOwnPlayerVeh = protectedKey.onlyForOwnPlayerVeh -- if key has &amp;quot;self-vehicle&amp;quot; lock&lt;br /&gt;
	local allowForElements = protectedKey.allowForElements -- if key has element type check&lt;br /&gt;
	local allowedDataTypes = protectedKey.allowedDataTypes -- if key has allowed data type check&lt;br /&gt;
&lt;br /&gt;
	if (onlyForPlayerHimself) then -- if &amp;quot;self-set&amp;quot; lock is active&lt;br /&gt;
		local matchingElement = (clientElement == sourceElement) -- verify whether player who set data is equal to element which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElement) then -- if it's not matching&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player himself&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (onlyForOwnPlayerVeh) then -- if &amp;quot;self-vehicle&amp;quot; lock is active&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(clientElement) -- get current vehicle of player which set data&lt;br /&gt;
		local matchingVehicle = (playerVehicle == sourceElement) -- check whether it matches the one which received data&lt;br /&gt;
&lt;br /&gt;
		if (not matchingVehicle) then -- if it doesn't match&lt;br /&gt;
			local failReason = &amp;quot;Can only set on player's own vehicle&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowForElements) then -- check if it's one of them&lt;br /&gt;
		local elementType = getElementType(sourceElement) -- get type of element whose data changed&lt;br /&gt;
		local matchingElementType = allowForElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingElementType) then -- this isn't matching&lt;br /&gt;
			local failReason = &amp;quot;Invalid element type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (allowedDataTypes) then -- if there's allowed data types&lt;br /&gt;
		local valueType = type(newValue) -- get data type of value&lt;br /&gt;
		local matchingType = allowedDataTypes[valueType] -- check if it's one of allowed&lt;br /&gt;
&lt;br /&gt;
		if (not matchingType) then -- if it's not then&lt;br /&gt;
			local failReason = &amp;quot;Invalid data type&amp;quot; -- reason shown in report&lt;br /&gt;
			local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
			reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedStringLength = protectedKey.allowedStringLength -- if key has specified string length check&lt;br /&gt;
		local dataString = (valueType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
		if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
			local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
			local stringLength = utf8.len(newValue) -- get length of data string&lt;br /&gt;
			local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedTableLength = protectedKey.allowedTableLength -- if key has table length check&lt;br /&gt;
		local dataTable = (valueType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
		if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
			local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
			local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
			local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
			local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
			local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
			for _, _ in pairs(newValue) do -- loop through whole table&lt;br /&gt;
				tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
				minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
				maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
				if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
					break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
			if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
				local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local allowedNumberRange = protectedKey.allowedNumberRange -- if key has allowed number range check&lt;br /&gt;
		local dataNumber = (valueType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
		if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
			local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
			local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
			local matchingRange = (newValue &amp;gt;= minRange) and (newValue &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
			if (not matchingRange) then -- if it doesn't&lt;br /&gt;
				local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;)&amp;quot; -- reason shown in report&lt;br /&gt;
				local forceRemove = false -- should key be completely removed&lt;br /&gt;
&lt;br /&gt;
				reportAndRevertDataChange(clientElement, sourceElement, dataKey, oldValue, newValue, failReason, forceRemove) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this data key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onElementDataChangeAdvancedAC(dataKey, oldValue, newValue) -- this event makes use of handleDataChange, the code was split for better readability&lt;br /&gt;
	if (not client) then -- check if data is coming from client&lt;br /&gt;
		return false -- if it's not, do not continue&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedChange = handleDataChange(client, source, dataKey, oldValue, newValue) -- run our security checks&lt;br /&gt;
&lt;br /&gt;
	if (approvedChange) then -- it's all cool and good&lt;br /&gt;
		return false -- we don't need further action&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(client, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(client, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onElementDataChange&amp;quot;, root, onElementDataChangeAdvancedAC)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing triggerServerEvent==&lt;br /&gt;
&lt;br /&gt;
* All parameters including '''source''' can be faked and should not be trusted.&lt;br /&gt;
* Global variable '''client''' can be trusted.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player (client) '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Example of comfortable anti-cheat function designed for events, used for data validation for both normal, and admin events which are called from client-side.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
--[[&lt;br /&gt;
	For maximum security set punishPlayerOnDetect, punishmentBan to true (as per default configuration)&lt;br /&gt;
&lt;br /&gt;
	Anti-cheat (processServerEventData) table structure and it's options:&lt;br /&gt;
&lt;br /&gt;
	checkACLGroup = { -- check whether player who called event belongs to at least one group below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;Admin&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkPermissions = { -- check whether player who called event has permission to at least one thing below, set to false/nil to not check this&lt;br /&gt;
		&amp;quot;function.kickPlayer&amp;quot;,&lt;br /&gt;
	},&lt;br /&gt;
	checkEventData = {&lt;br /&gt;
		{&lt;br /&gt;
			debugData = &amp;quot;source&amp;quot;, -- optional details for report shown in debug message&lt;br /&gt;
			eventData = source, -- data we want to verify&lt;br /&gt;
			equalTo = client, -- compare whether eventData == equalTo&lt;br /&gt;
			allowedElements = { -- restrict eventData to be certain element type(s), set to false/nil or leave it empty to not check this (full list of element types: https://wiki.multitheftauto.com/wiki/GetElementsByType)&lt;br /&gt;
				[&amp;quot;player&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;ped&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;vehicle&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;object&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedDataTypes = { -- restrict eventData to be certain value type(s), set to false/nil or leave it empty to not check this&lt;br /&gt;
				[&amp;quot;string&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;number&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;table&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;boolean&amp;quot;] = true,&lt;br /&gt;
				[&amp;quot;nil&amp;quot;] = true,&lt;br /&gt;
			},&lt;br /&gt;
			allowedStringLength = {1, 32}, -- if eventData is a string, then it's length must be in between (min-max), set it to false/nil to not check string length - do note that allowedDataTypes must contain [&amp;quot;string&amp;quot;] = true&lt;br /&gt;
			allowedTableLength = {1, 64}, -- if eventData is a table, then it's length must be in between (min-max), set it to false/nil to not check table length - do note that allowedDataTypes must contain [&amp;quot;table&amp;quot;] = true&lt;br /&gt;
			allowedNumberRange = {1, 128}, -- if eventData is a number, then it must be in between (min-max), set it to false/nil to not check number range - do note that allowedDataTypes must contain [&amp;quot;number&amp;quot;] = true&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
local punishPlayerOnDetect = true -- should player be punished upon detection (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Altering server event data&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugR = 255 -- debug message - red color&lt;br /&gt;
local debugG = 127 -- debug message - green color&lt;br /&gt;
local debugB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
function processServerEventData(clientElement, sourceElement, serverEvent, securityChecks) -- the heart of our anti-cheat, which does all the magic security measurements, returns true if there was no altering from client (based on data from securityChecks), false otherwise&lt;br /&gt;
	if (not securityChecks) then -- if we haven't passed any security checks&lt;br /&gt;
		return true -- nothing to check, let code go further&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	if (not clientElement) then -- if client variable isn't available for some reason (although it should never happen)&lt;br /&gt;
		local failReason = &amp;quot;Client variable not present&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local checkACLGroup = securityChecks.checkACLGroup -- if there's any ACL groups to check&lt;br /&gt;
	local checkPermissions = securityChecks.checkPermissions -- if there's any permissions to check&lt;br /&gt;
	local checkEventData = securityChecks.checkEventData -- if there's any data checks&lt;br /&gt;
&lt;br /&gt;
	if (checkACLGroup) then -- let's check player ACL groups&lt;br /&gt;
		local playerAccount = getPlayerAccount(clientElement) -- get current account of player&lt;br /&gt;
		local guestAccount = isGuestAccount(playerAccount) -- if account is guest (meaning player is not logged in)&lt;br /&gt;
&lt;br /&gt;
		if (guestAccount) then -- it's the case&lt;br /&gt;
			local failReason = &amp;quot;Can't retrieve player login - guest account&amp;quot; -- reason shown in report&lt;br /&gt;
			local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
			reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
			return false -- return failure&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local accountName = getAccountName(playerAccount) -- get name of player's current account&lt;br /&gt;
		local aclString = &amp;quot;user.&amp;quot;..accountName -- format it for further use in isObjectInACLGroup function&lt;br /&gt;
&lt;br /&gt;
		for groupID = 1, #checkACLGroup do -- iterate over table of given groups&lt;br /&gt;
			local groupName = checkACLGroup[groupID] -- get each group name&lt;br /&gt;
			local aclGroup = aclGetGroup(groupName) -- check if such group exists&lt;br /&gt;
&lt;br /&gt;
			if (not aclGroup) then -- it doesn't&lt;br /&gt;
				local failReason = &amp;quot;ACL group '&amp;quot;..groupName..&amp;quot;' is missing&amp;quot; -- reason shown in report&lt;br /&gt;
				local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
				reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
				return false -- return failure&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local playerInACLGroup = isObjectInACLGroup(aclString, aclGroup) -- check if player belong to the group&lt;br /&gt;
&lt;br /&gt;
			if (playerInACLGroup) then -- yep, it's the case&lt;br /&gt;
				return true -- so it's a success&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Player doesn't belong to any given ACL group&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkPermissions) then -- check if player has at least one desired permission&lt;br /&gt;
		local allowedByDefault = false -- does he have access by default&lt;br /&gt;
&lt;br /&gt;
		for permissionID = 1, #checkPermissions do -- iterate over all permissions&lt;br /&gt;
			local permissionName = checkPermissions[permissionID] -- get permission name&lt;br /&gt;
			local hasPermission = hasObjectPermissionTo(clientElement, permissionName, allowedByDefault) -- check whether player is allowed to perform certain action&lt;br /&gt;
&lt;br /&gt;
			if (hasPermission) then -- if player has access&lt;br /&gt;
				return true -- one is available (and enough), server won't bother to check others (as return keywords also breaks loop)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local failReason = &amp;quot;Not enough permissions&amp;quot; -- reason shown in report&lt;br /&gt;
		local skipPunishment = true -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
		reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
		return false -- return failure&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if (checkEventData) then -- if there is some data to verify&lt;br /&gt;
&lt;br /&gt;
		for dataID = 1, #checkEventData do -- iterate over each of data&lt;br /&gt;
			local dataToCheck = checkEventData[dataID] -- get each data set&lt;br /&gt;
			local eventData = dataToCheck.eventData -- this is the one we'll be verifying&lt;br /&gt;
			local equalTo = dataToCheck.equalTo -- we want to compare whether eventData == equalTo&lt;br /&gt;
			local allowedElements = dataToCheck.allowedElements -- check whether is element, and whether belongs to certain element types&lt;br /&gt;
			local allowedDataTypes = dataToCheck.allowedDataTypes -- do we restrict data to be certain type?&lt;br /&gt;
			local debugData = dataToCheck.debugData -- additional helper data&lt;br /&gt;
			local debugText = debugData and &amp;quot; (&amp;quot;..debugData..&amp;quot;)&amp;quot; or &amp;quot;&amp;quot; -- if it's present, format it nicely&lt;br /&gt;
&lt;br /&gt;
			if (equalTo) then -- equal check exists&lt;br /&gt;
				local matchingData = (eventData == equalTo) -- compare whether those two values are equal&lt;br /&gt;
&lt;br /&gt;
				if (not matchingData) then -- they aren't&lt;br /&gt;
					local failReason = &amp;quot;Data isn't equal @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedElements) then -- we do check whether is an element, and belongs to at least one given in the list&lt;br /&gt;
				local validElement = isElement(eventData) -- check if it's actual element&lt;br /&gt;
&lt;br /&gt;
				if (not validElement) then -- it's not&lt;br /&gt;
					local failReason = &amp;quot;Data isn't element @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local elementType = getElementType(eventData) -- it's element, so we want to know it's type&lt;br /&gt;
				local matchingElementType = allowedElements[elementType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingElementType) then -- it's not allowed&lt;br /&gt;
					local failReason = &amp;quot;Invalid element type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			if (allowedDataTypes) then -- let's check allowed data types&lt;br /&gt;
				local dataType = type(eventData) -- get data type&lt;br /&gt;
				local matchingType = allowedDataTypes[dataType] -- verify whether it's allowed&lt;br /&gt;
&lt;br /&gt;
				if (not matchingType) then -- it isn't&lt;br /&gt;
					local failReason = &amp;quot;Invalid data type @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
					local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
					reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
					return false -- return failure&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedStringLength = dataToCheck.allowedStringLength -- if data has string length check&lt;br /&gt;
				local dataString = (dataType == &amp;quot;string&amp;quot;) -- make sure it's a string&lt;br /&gt;
&lt;br /&gt;
				if (allowedStringLength and dataString) then -- if we should check string length&lt;br /&gt;
					local minLength = allowedStringLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedStringLength[2] -- retrieve max length&lt;br /&gt;
					local stringLength = utf8.len(eventData) -- get length of data string&lt;br /&gt;
					local matchingLength = (stringLength &amp;gt;= minLength) and (stringLength &amp;lt;= maxLength) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid string length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedTableLength = dataToCheck.allowedTableLength -- if data has table length check&lt;br /&gt;
				local dataTable = (dataType == &amp;quot;table&amp;quot;) -- make sure it's a table&lt;br /&gt;
&lt;br /&gt;
				if (allowedTableLength and dataTable) then -- if we should check table length&lt;br /&gt;
					local minLength = allowedTableLength[1] -- retrieve min length&lt;br /&gt;
					local maxLength = allowedTableLength[2] -- retrieve max length&lt;br /&gt;
					local minLengthAchieved = false -- variable which checks 'does minimum length was achieved'&lt;br /&gt;
					local maxLengthExceeded = false -- variable which checks 'does length has exceeds more than allowed maximum'&lt;br /&gt;
					local tableLength = 0 -- store initial table length&lt;br /&gt;
&lt;br /&gt;
					for _, _ in pairs(eventData) do -- loop through whole table&lt;br /&gt;
						tableLength = (tableLength + 1) -- add + 1 on each table entry&lt;br /&gt;
						minLengthAchieved = (tableLength &amp;gt;= minLength) -- is length bigger or at very minimum we require&lt;br /&gt;
						maxLengthExceeded = (tableLength &amp;gt; maxLength) -- does table exceeded more than max length?&lt;br /&gt;
&lt;br /&gt;
						if (maxLengthExceeded) then -- it is bigger than it should be&lt;br /&gt;
							break -- break the loop (due of condition above being worthy, it makes no point to count further and waste CPU, on a table which potentially could have huge amount of entries)&lt;br /&gt;
						end&lt;br /&gt;
					end&lt;br /&gt;
&lt;br /&gt;
					local matchingLength = (minLengthAchieved and not maxLengthExceeded) -- check if min length has been achieved, and make sure that it doesn't go beyond max length&lt;br /&gt;
&lt;br /&gt;
					if (not matchingLength) then -- this table doesn't match requirements&lt;br /&gt;
						local failReason = &amp;quot;Invalid table length (must be between &amp;quot;..minLength..&amp;quot;-&amp;quot;..maxLength..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
&lt;br /&gt;
				local allowedNumberRange = dataToCheck.allowedNumberRange -- if data has number range check&lt;br /&gt;
				local dataNumber = (dataType == &amp;quot;number&amp;quot;) -- make sure it's a number&lt;br /&gt;
&lt;br /&gt;
				if (allowedNumberRange and dataNumber) then -- if we should check number range&lt;br /&gt;
					local minRange = allowedNumberRange[1] -- retrieve min number range&lt;br /&gt;
					local maxRange = allowedNumberRange[2] -- retrieve max number range&lt;br /&gt;
					local matchingRange = (eventData &amp;gt;= minRange) and (eventData &amp;lt;= maxRange) -- compare whether value fits in between&lt;br /&gt;
&lt;br /&gt;
					if (not matchingRange) then -- if it doesn't&lt;br /&gt;
						local failReason = &amp;quot;Invalid number range (must be between &amp;quot;..minRange..&amp;quot;-&amp;quot;..maxRange..&amp;quot;) @ argument &amp;quot;..dataID..debugText -- reason shown in report&lt;br /&gt;
						local skipPunishment = false -- should server skip punishment&lt;br /&gt;
&lt;br /&gt;
						reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- report accident, and handle (or not) this player&lt;br /&gt;
&lt;br /&gt;
						return false -- return failure&lt;br /&gt;
					end&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- security checks passed, we are all clear with this event call&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function reportAndHandleEventAbnormality(clientElement, sourceElement, serverEvent, failReason, skipPunishment) -- helper function to log and handle accidents&lt;br /&gt;
	local logClient = inspect(clientElement) -- in-depth view player which called event&lt;br /&gt;
	local logSerial = getPlayerSerial(clientElement) or &amp;quot;N/A&amp;quot; -- client serial, or &amp;quot;N/A&amp;quot; if not possible, for some reason&lt;br /&gt;
	local logSource = inspect(sourceElement) -- in-depth view of source element&lt;br /&gt;
	local logText = -- fill our report with data&lt;br /&gt;
		&amp;quot;*\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Detected event abnormality:\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client: &amp;quot;..logClient..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Client serial: &amp;quot;..logSerial..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Source: &amp;quot;..logSource..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Event: &amp;quot;..serverEvent..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Reason: &amp;quot;..failReason..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;*&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(logText, debugLevel, debugR, debugG, debugB) -- print it to debug&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect or skipPunishment) then -- we don't want to punish player for some reason&lt;br /&gt;
		return true -- stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(clientElement, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(clientElement, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true -- all done, report success&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onServerEvent(clientData)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local dataToPass = 10&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerEvent&amp;quot;, localPlayer, dataToPass)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = clientData, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;number&amp;quot;] = true, -- we want it to be only number&lt;br /&gt;
					},&lt;br /&gt;
					allowedNumberRange = {1, 100}, -- in range of 1 to 100&lt;br /&gt;
					debugData = &amp;quot;clientData&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerEvent&amp;quot;, root, onServerEvent)&lt;br /&gt;
&lt;br /&gt;
function onServerAdminEvent(playerToBan)&lt;br /&gt;
	--[[&lt;br /&gt;
		Assume this server admin event (function) is called in such way:&lt;br /&gt;
&lt;br /&gt;
		local playerToBan = getPlayerFromName(&amp;quot;playerToBan&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
		triggerServerEvent(&amp;quot;onServerAdminEvent&amp;quot;, localPlayer, playerToBan)&lt;br /&gt;
	]]&lt;br /&gt;
&lt;br /&gt;
	local shouldProcessServerCode = processServerEventData(&lt;br /&gt;
		client, -- client element - responsible for calling event&lt;br /&gt;
		source, -- source element - passed in triggerServerEvent (as 2nd argument)&lt;br /&gt;
		eventName, -- name of event - in this case 'onServerAdminEvent'&lt;br /&gt;
		{&lt;br /&gt;
			checkACLGroup = { -- we need to check whether player who called event belongs to ACL groups&lt;br /&gt;
				&amp;quot;Admin&amp;quot;, -- in this case admin group&lt;br /&gt;
			},&lt;br /&gt;
			checkEventData = { -- we want to verify everything what comes from client&lt;br /&gt;
				{&lt;br /&gt;
					eventData = source, -- first to check, source variable&lt;br /&gt;
					equalTo = client, -- we want to check whether it matches player who called event&lt;br /&gt;
					debugData = &amp;quot;source&amp;quot;, -- helper details which would be shown in report&lt;br /&gt;
				},&lt;br /&gt;
				{&lt;br /&gt;
					eventData = playerToBan, -- let's check the data which client sent to us&lt;br /&gt;
					allowedDataTypes = {&lt;br /&gt;
						[&amp;quot;player&amp;quot;] = true, -- we want it to be player&lt;br /&gt;
					},&lt;br /&gt;
					debugData = &amp;quot;playerToBan&amp;quot;, -- if something goes wrong, let server know where (it will appear in debug report)&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
		}&lt;br /&gt;
	)&lt;br /&gt;
&lt;br /&gt;
	if (not shouldProcessServerCode) then -- something isn't right, no green light for processing code behind this scope&lt;br /&gt;
		return false -- stop code execution&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- do code as usual&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerAdminEvent&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;onServerAdminEvent&amp;quot;, root, onServerAdminEvent)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing server-only events==&lt;br /&gt;
* It is very important to '''disable remote triggering''' ability in [https://wiki.multitheftauto.com/wiki/AddEvent addEvent], to prevent calling server-side only events from client-side.&lt;br /&gt;
* '''Admin''' styled '''events''' should be verifying player '''ACL rights''', either by [https://wiki.multitheftauto.com/wiki/IsObjectInACLGroup isObjectInACLGroup] or [https://wiki.multitheftauto.com/wiki/HasObjectPermissionTo hasObjectPermissionTo].&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example shows how you should make event server-side only.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function onServerSideOnlyEvent()&lt;br /&gt;
	-- do some server-side stuff&lt;br /&gt;
end&lt;br /&gt;
addEvent(&amp;quot;onServerSideOnlyEvent&amp;quot;, false) -- set second argument (allowRemoteTriger) to false, so it can't be called from client&lt;br /&gt;
addEventHandler(&amp;quot;onServerSideOnlyEvent&amp;quot;, root, onServerSideOnlyEvent) -- associate our event with function onServerSideOnlyEvent&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Securing projectiles &amp;amp; explosions==&lt;br /&gt;
This section (and '''code''' is '''work in progress''') - '''use at your own risk'''.&lt;br /&gt;
&lt;br /&gt;
----------&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile ammo tracker:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerProjectileAmmo = {} -- store player-held weapons ammo here&lt;br /&gt;
local playerWeaponsToTrack = { -- keep track of ammo for certain player-held weapon types, basically those which create projectile; [weaponID] = weaponSlot&lt;br /&gt;
	[16] = 8, -- grenade&lt;br /&gt;
	[17] = 8, -- teargas&lt;br /&gt;
	[18] = 8, -- molotov&lt;br /&gt;
	[35] = 7, -- rocket launcher&lt;br /&gt;
	[36] = 7, -- rocket launcher (heat-seeking)&lt;br /&gt;
	[39] = 8, -- satchel charge&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	for weaponID, weaponSlot in pairs(playerWeaponsToTrack) do&lt;br /&gt;
		local weaponInSlot = getPedWeapon(playerElement, weaponSlot)&lt;br /&gt;
		local weaponTotalAmmo = getPedTotalAmmo(playerElement, weaponSlot)&lt;br /&gt;
		local weaponHasAmmo = (weaponTotalAmmo &amp;gt; 0)&lt;br /&gt;
		local weaponMatching = (weaponInSlot == weaponID)&lt;br /&gt;
		local updateWeaponAmmo = (weaponMatching and weaponHasAmmo)&lt;br /&gt;
&lt;br /&gt;
		if (updateWeaponAmmo) then&lt;br /&gt;
			local storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			local newWeaponAmmo = (updateWeaponAmmo and weaponTotalAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
			if (not storedProjectileAmmo) then&lt;br /&gt;
				playerProjectileAmmo[playerElement] = {}&lt;br /&gt;
				storedProjectileAmmo = playerProjectileAmmo[playerElement]&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			storedProjectileAmmo[weaponID] = newWeaponAmmo&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function hasPlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
	local projectileAmmo = (projectileData and projectileData[projectileWeapon])&lt;br /&gt;
&lt;br /&gt;
	return projectileAmmo&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectileAmmo(playerElement, projectileWeapon)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerDead = isPedDead(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerDead) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectileData = playerProjectileAmmo[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectileData) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local projectileWeaponAmmo = playerProjectileData[projectileWeapon]&lt;br /&gt;
	local tempProjectileAmmo = (projectileWeaponAmmo - 1)&lt;br /&gt;
	local newProjectileAmmo = (tempProjectileAmmo &amp;gt; 0 and tempProjectileAmmo or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectileData[projectileWeapon] = newProjectileAmmo&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerWeaponSwitchAntiCheat(previousWeaponID, currentWeaponID)&lt;br /&gt;
	setTimer(updateProjectileAmmoForPlayer, 50, 1, source)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWeaponSwitch&amp;quot;, root, onPlayerWeaponSwitchAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onResourceStartAntiCheat()&lt;br /&gt;
	local playersTable = getElementsByType(&amp;quot;player&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
	for playerID = 1, #playersTable do&lt;br /&gt;
		local playerElement = playersTable[playerID]&lt;br /&gt;
&lt;br /&gt;
		updateProjectileAmmoForPlayer(playerElement)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, resourceRoot, onResourceStartAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerWastedQuitAntiCheat()&lt;br /&gt;
	playerProjectileAmmo[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerWasted&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerWastedQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Projectile handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerCreatedProjectiles = {} -- store count of legitimately created player projectiles; [playerElement] = {[projectileType] = activeProjectiles}&lt;br /&gt;
local projectileTypes = {&lt;br /&gt;
	[16] = { -- Grenade&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[17] = { -- Teargas&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[17] = true, -- teargas&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[18] = { -- Molotov&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[19] = { -- Rocket&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[425] = true, -- hunter&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[20] = { -- Rocket (heat-seeking)&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileMaxVelocity = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[21] = { -- Airbomb&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[39] = { -- Satchel charge&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 2,&lt;br /&gt;
		projectileAllowedWeapons = {&lt;br /&gt;
			[39] = true, -- satchel charge&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[58] = { -- Hydra flare&lt;br /&gt;
		projectileAllowed = true,&lt;br /&gt;
		projectileMaxDistanceFromCreator = 5,&lt;br /&gt;
		projectileAllowedVehicles = {&lt;br /&gt;
			[520] = true, -- hydra&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportProjectileAbnormality(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	local projectileSyncer = inspect(playerElement)&lt;br /&gt;
	local projectilePosition = (projectileX..&amp;quot;, &amp;quot;..projectileY..&amp;quot;, &amp;quot;..projectileZ)&lt;br /&gt;
	local projectileZoneName = getZoneName(projectileX, projectileY, projectileZ, false)&lt;br /&gt;
	local projectileCityName = getZoneName(projectileX, projectileY, projectileZ, true)&lt;br /&gt;
	local projectileLog =&lt;br /&gt;
		&amp;quot;* Detected projectile abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile syncer: &amp;quot;..projectileSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile type: &amp;quot;..projectileType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Projectile position: &amp;quot;..projectilePosition.. &amp;quot; (&amp;quot;..projectileZoneName..&amp;quot;, &amp;quot;..projectileCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(projectileLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processProjectileChecks(playerElement, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
	local projectileAllowed = projectileData.projectileAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not projectileAllowed) then&lt;br /&gt;
		return false, &amp;quot;Projectile not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileAllowedWeapons = projectileData.projectileAllowedWeapons&lt;br /&gt;
&lt;br /&gt;
	if (projectileAllowedWeapons) then&lt;br /&gt;
		local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
		local allowedWeapon = projectileAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedWeapon) then&lt;br /&gt;
			return false, &amp;quot;Player is not holding correct weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
		local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
		if (not playerHasAmmo) then&lt;br /&gt;
			return false, &amp;quot;Player doesn't have ammo for weapon&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (playerVehicle) then&lt;br /&gt;
		local projectileAllowedVehicles = projectileData.projectileAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
		if (projectileAllowedVehicles) then&lt;br /&gt;
			local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
			local allowedVehicle = projectileAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedVehicle) then&lt;br /&gt;
				return false, &amp;quot;Player is not inside allowed vehicles&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
			local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
			if (not playerDriver) then&lt;br /&gt;
				return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Player in vehicle&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxDistanceFromCreator = projectileData.projectileMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToProjectile = getDistanceBetweenPoints3D(playerX, playerY, playerZ, projectileX, projectileY, projectileZ)&lt;br /&gt;
		local matchingProjectileDistance = (distanceToProjectile &amp;lt;= projectileMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileDistance) then&lt;br /&gt;
			return false, &amp;quot;Projectile distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileMaxVelocity = projectileData.projectileMaxVelocity&lt;br /&gt;
&lt;br /&gt;
	if (projectileMaxVelocity) then&lt;br /&gt;
		local projectileVelocity = (projectileVX ^ 2 + projectileVY ^ 2 + projectileVZ ^ 2)&lt;br /&gt;
		local projectileSpeed = math.sqrt(projectileVelocity)&lt;br /&gt;
		local matchingProjectileVelocity = (projectileSpeed &amp;lt;= projectileMaxVelocity)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingProjectileVelocity) then&lt;br /&gt;
			return false, &amp;quot;Projectile velocity mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function trackPlayerProjectile(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		playerCreatedProjectiles[playerElement] = {}&lt;br /&gt;
		playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID] or 0&lt;br /&gt;
	local newProjectilesCount = (projectilesByType + 1)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
	local projectileData = projectileTypes[projectileType]&lt;br /&gt;
&lt;br /&gt;
	if (not projectileData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectileBehaviour = projectileData.projectileOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not projectileBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = projectileBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = projectileBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = projectileBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
	local validElement = isElement(playerElement)&lt;br /&gt;
&lt;br /&gt;
	if (not validElement) then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local playerProjectiles = playerCreatedProjectiles[playerElement]&lt;br /&gt;
&lt;br /&gt;
	if (not playerProjectiles) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local projectilesByType = playerProjectiles[projectileID]&lt;br /&gt;
&lt;br /&gt;
	if (not projectilesByType) then&lt;br /&gt;
		return false, true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local tempProjectilesCount = (projectilesByType - 1)&lt;br /&gt;
	local newProjectilesCount = (tempProjectilesCount &amp;gt; 0 and tempProjectilesCount or nil)&lt;br /&gt;
&lt;br /&gt;
	playerProjectiles[projectileID] = newProjectilesCount&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onPlayerProjectileCreationAntiCheat(projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
	local approvedProjectile, detectionCode = processProjectileChecks(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedProjectile) then&lt;br /&gt;
		trackPlayerProjectile(source, projectileType)&lt;br /&gt;
&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getProjectileDetectionOverwrittenBehavior(projectileType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportProjectileAbnormality(source, projectileType, projectileX, projectileY, projectileZ, projectileForce, projectileTarget, projectileRX, projectileRY, projectileRZ, projectileVX, projectileVY, projectileVZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerProjectileCreation&amp;quot;, root, onPlayerProjectileCreationAntiCheat)&lt;br /&gt;
&lt;br /&gt;
function onPlayerQuitAntiCheat()&lt;br /&gt;
	playerCreatedProjectiles[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onPlayerQuitAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
Explosions handler:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local rocketInstantExplosionDistanceThreshold = 1.55 -- distance below which only explosion will be created (and not rocket projectile, hence not calling onPlayerProjectileCreation); do not change it&lt;br /&gt;
local explosionTypes = { -- more specific info on explosion, and whether it is allowed&lt;br /&gt;
	[0] = { -- Grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[16] = true, -- grenade&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[1] = { -- Molotov&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[18] = true, -- molotov&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[2] = { -- Rocket&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedWeapons = {&lt;br /&gt;
			[35] = true, -- rocket launcher&lt;br /&gt;
			[36] = true, -- rocket launcher (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[3] = { -- Rocket weak&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionAllowedProjectiles = {&lt;br /&gt;
			[19] = true, -- rocket&lt;br /&gt;
			[20] = true, -- rocket (heat-seeking)&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
	[4] = { -- Car&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[5] = { -- Car quick&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[6] = { -- Boat&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[7] = { -- Heli&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[8] = { -- Mine&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[9] = { -- Object&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[10] = { -- Tank grenade&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
		explosionMaxDistanceFromCreator = 80,&lt;br /&gt;
		explosionAllowedVehicles = {&lt;br /&gt;
			[432] = true,&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
	[11] = { -- Small&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
	[12] = { -- Tiny&lt;br /&gt;
		explosionAllowed = true,&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local reportAbnormality = true -- whether to report about abnormality in debug script - by default&lt;br /&gt;
local punishPlayerOnDetect = false -- should player be punished upon detection; true - yes, or false to not do anything (make sure that resource which runs this code has admin rights)&lt;br /&gt;
local punishmentBan = true -- only relevant if punishPlayerOnDetect is set to true; use true for ban or false for kick&lt;br /&gt;
local punishmentReason = &amp;quot;Projectile/explosion anti-cheat&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; reason which would be shown to punished player&lt;br /&gt;
local punishedBy = &amp;quot;Console&amp;quot; -- only relevant if punishPlayerOnDetect is set to true; who was responsible for punishing, as well shown to punished player&lt;br /&gt;
local banByIP = false -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; banning by IP nowadays is not recommended (...)&lt;br /&gt;
local banByUsername = false -- community username - legacy thing, hence is set to false and should stay like that&lt;br /&gt;
local banBySerial = true -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; (...) if there is a player serial to use instead&lt;br /&gt;
local banTime = 0 -- only relevant if punishPlayerOnDetect and punishmentBan is set to true; time in seconds, 0 for permanent&lt;br /&gt;
local debugMsgLevel = 4 -- this debug level allows to hide INFO: prefix, and use custom colors&lt;br /&gt;
local debugMsgR = 255 -- debug message - red color&lt;br /&gt;
local debugMsgG = 127 -- debug message - green color&lt;br /&gt;
local debugMsgB = 0 -- debug message - blue color&lt;br /&gt;
&lt;br /&gt;
local function reportExplosionAbnormality(playerElement, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	local explosionSyncer = inspect(playerElement)&lt;br /&gt;
	local explosionType = explosionType&lt;br /&gt;
	local explosionPosition = (explosionX..&amp;quot;, &amp;quot;..explosionY..&amp;quot;, &amp;quot;..explosionZ)&lt;br /&gt;
	local explosionZoneName = getZoneName(explosionX, explosionY, explosionZ, false)&lt;br /&gt;
	local explosionCityName = getZoneName(explosionX, explosionY, explosionZ, true)&lt;br /&gt;
	local explosionLog =&lt;br /&gt;
		&amp;quot;* Detected explosion abnormality - &amp;quot;..detectionCode..&amp;quot; *\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion syncer: &amp;quot;..explosionSyncer..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion type: &amp;quot;..explosionType..&amp;quot;\n&amp;quot;..&lt;br /&gt;
		&amp;quot;Explosion position: &amp;quot;..explosionPosition.. &amp;quot; (&amp;quot;..explosionZoneName..&amp;quot;, &amp;quot;..explosionCityName..&amp;quot;)\n&amp;quot;&lt;br /&gt;
&lt;br /&gt;
	outputDebugString(explosionLog, debugMsgLevel, debugMsgR, debugMsgG, debugMsgB)&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function processExplosionChecks(playerElement, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
	local explosionAllowed = explosionData.explosionAllowed&lt;br /&gt;
&lt;br /&gt;
	if (not explosionAllowed) then&lt;br /&gt;
		return false, &amp;quot;Explosion type not allowed&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local rocketExplosion = (explosionType == 2)&lt;br /&gt;
&lt;br /&gt;
	if (rocketExplosion) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local instantExplosion = (distanceToExplosion &amp;lt; rocketInstantExplosionDistanceThreshold)&lt;br /&gt;
&lt;br /&gt;
		if (instantExplosion) then&lt;br /&gt;
			local explosionAllowedWeapons = explosionData.explosionAllowedWeapons&lt;br /&gt;
			local playerWeapon = getPedWeapon(playerElement)&lt;br /&gt;
			local allowedWeapon = explosionAllowedWeapons[playerWeapon]&lt;br /&gt;
&lt;br /&gt;
			if (not allowedWeapon) then&lt;br /&gt;
				return false, &amp;quot;Player is not holding rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			local weaponAmmo = hasPlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
			local playerHasAmmo = (weaponAmmo &amp;gt; 0)&lt;br /&gt;
&lt;br /&gt;
			if (not playerHasAmmo) then&lt;br /&gt;
				return false, &amp;quot;Player doesn't have ammo for rocket launcher&amp;quot;&lt;br /&gt;
			end&lt;br /&gt;
&lt;br /&gt;
			decreasePlayerProjectileAmmo(playerElement, playerWeapon)&lt;br /&gt;
&lt;br /&gt;
			return true&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedProjectiles = explosionData.explosionAllowedProjectiles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedProjectiles) then&lt;br /&gt;
&lt;br /&gt;
		for projectileID, _ in pairs(explosionAllowedProjectiles) do&lt;br /&gt;
			local atleastOneProjectile = decreasePlayerProjectiles(playerElement, projectileID)&lt;br /&gt;
&lt;br /&gt;
			if (atleastOneProjectile) then&lt;br /&gt;
				return true&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		return false, &amp;quot;Explosion created without respective projectile&amp;quot;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionAllowedVehicles = explosionData.explosionAllowedVehicles&lt;br /&gt;
&lt;br /&gt;
	if (explosionAllowedVehicles) then&lt;br /&gt;
		local playerVehicle = getPedOccupiedVehicle(playerElement)&lt;br /&gt;
&lt;br /&gt;
		if (not playerVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is not in vehicle&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleModel = getElementModel(playerVehicle)&lt;br /&gt;
		local allowedVehicle = explosionAllowedVehicles[vehicleModel]&lt;br /&gt;
&lt;br /&gt;
		if (not allowedVehicle) then&lt;br /&gt;
			return false, &amp;quot;Player is inside not allowed vehicles&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		local vehicleDriver = getVehicleController(playerVehicle)&lt;br /&gt;
		local playerDriver = (playerElement == vehicleDriver)&lt;br /&gt;
&lt;br /&gt;
		if (not playerDriver) then&lt;br /&gt;
			return false, &amp;quot;Player is not vehicle driver&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionMaxDistanceFromCreator = explosionData.explosionMaxDistanceFromCreator&lt;br /&gt;
&lt;br /&gt;
	if (explosionMaxDistanceFromCreator) then&lt;br /&gt;
		local playerX, playerY, playerZ = getElementPosition(playerElement)&lt;br /&gt;
		local distanceToExplosion = getDistanceBetweenPoints3D(playerX, playerY, playerZ, explosionX, explosionY, explosionZ)&lt;br /&gt;
		local matchingExplosionDistance = (distanceToExplosion &amp;lt; explosionMaxDistanceFromCreator)&lt;br /&gt;
&lt;br /&gt;
		if (not matchingExplosionDistance) then&lt;br /&gt;
			return false, &amp;quot;Explosion distance mismatch&amp;quot;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
	local explosionData = explosionTypes[explosionType]&lt;br /&gt;
&lt;br /&gt;
	if (not explosionData) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local explosionBehaviour = explosionData.explosionOverwriteBehaviour&lt;br /&gt;
&lt;br /&gt;
	if (not explosionBehaviour) then&lt;br /&gt;
		return reportAbnormality, punishPlayerOnDetect, punishmentBan&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local overwriteReport = explosionBehaviour.reportAbnormality&lt;br /&gt;
	local overwritePunish = explosionBehaviour.punishPlayerOnDetect&lt;br /&gt;
	local overwriteBan = explosionBehaviour.punishmentBan&lt;br /&gt;
&lt;br /&gt;
	return overwriteReport, overwritePunish, overwriteBan&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function onExplosionAntiCheat(explosionX, explosionY, explosionZ, explosionType)&lt;br /&gt;
	local serverSyncExplosion = (source == root)&lt;br /&gt;
&lt;br /&gt;
	if (serverSyncExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local approvedExplosion, detectionCode = processExplosionChecks(source, explosionType, explosionX, explosionY, explosionZ)&lt;br /&gt;
&lt;br /&gt;
	if (approvedExplosion) then&lt;br /&gt;
		return true&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local reportAbnormality, punishPlayerOnDetect, punishmentBan = getExplosionDetectionOverwrittenBehavior(explosionType)&lt;br /&gt;
&lt;br /&gt;
	if (reportAbnormality) then&lt;br /&gt;
		reportExplosionAbnormality(source, explosionType, explosionX, explosionY, explosionZ, detectionCode)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	cancelEvent()&lt;br /&gt;
&lt;br /&gt;
	if (not punishPlayerOnDetect) then -- we don't want to punish player for some reason&lt;br /&gt;
		return false -- so stop here&lt;br /&gt;
	end&lt;br /&gt;
		&lt;br /&gt;
	if (punishmentBan) then -- if it's ban&lt;br /&gt;
		banPlayer(source, banByIP, banByUsername, banBySerial, punishedBy, punishmentReason, banTime) -- remove his presence from server&lt;br /&gt;
	else -- otherwise&lt;br /&gt;
		kickPlayer(source, punishedBy, punishmentReason) -- simply kick player out of server&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onExplosion&amp;quot;, root, onExplosionAntiCheat)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Handling non-registered events==&lt;br /&gt;
&lt;br /&gt;
See: [[onPlayerTriggerInvalidEvent]]&lt;br /&gt;
&lt;br /&gt;
==Handling events spam==&lt;br /&gt;
See: [[onPlayerTriggerEventThreshold]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=User:CrosRoad95&amp;diff=79310</id>
		<title>User:CrosRoad95</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=User:CrosRoad95&amp;diff=79310"/>
		<updated>2024-05-12T09:58:06Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Blanked the page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=DxDrawModel3D&amp;diff=78234</id>
		<title>DxDrawModel3D</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=DxDrawModel3D&amp;diff=78234"/>
		<updated>2023-10-14T06:06:44Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}} &lt;br /&gt;
{{Important Note|You can not use this function to draw vehicles and ped}}&lt;br /&gt;
{{Important Note|This function doesn't obey any streaming limits, you can draw as many models as you want}}&lt;br /&gt;
{{Important Note|You can not render model to render target.}}&lt;br /&gt;
This function draws a 3D model - rendered for '''one''' frame. Drawn models are indistinguishable from this one created by [[createObject]] function. This should be used in conjunction with [[onClientRender]] in order to display continuously. &lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool dxDrawModel( int modelId, float positionX, float positionY, float positionZ, float rotationX, float rotationY, float rotationZ [, float scaleX, float scaleY, float scaleZ ])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DxDrawModel3D_at_day.png|thumb|Model during day]]&lt;br /&gt;
[[Image:DxDrawModel3D_at_night.png|thumb|Model during night]]&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
* '''modelId:''' Model you want to draw, must be regular object, you can not draw vehicles and peds&lt;br /&gt;
* '''positionX/Y/Z:''' Position of model&lt;br /&gt;
* '''rotationX/Y/Z:''' Rotation of model&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments===&lt;br /&gt;
* '''scaleX/Y/Z:''' Scale of model, by default {1,1,1}&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns true if the operation was successful, false otherwise.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Simple example&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onClientPreRender&amp;quot;, root, function()&lt;br /&gt;
    dxDrawModel3d(3276, -719.64984, 951.26685, 12.13281, 0, 0,90)&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Drawing_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=DxDrawModel3D&amp;diff=78233</id>
		<title>DxDrawModel3D</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=DxDrawModel3D&amp;diff=78233"/>
		<updated>2023-10-14T06:06:06Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;__NOTOC__  {{Client function}}  {{Important Note|You can not use this function to draw vehicles and ped}} {{Important Note|This function doesn't obey any streaming limits, you can draw as many models as you want}} {{Important Note|You can not render model to render target.}} This function draws a 3D model - rendered for '''one''' frame. Drawn models are indistinguishable from this one created by &amp;quot;createObject&amp;quot; function. This should be used in conjunction with onClientR...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}} &lt;br /&gt;
{{Important Note|You can not use this function to draw vehicles and ped}}&lt;br /&gt;
{{Important Note|This function doesn't obey any streaming limits, you can draw as many models as you want}}&lt;br /&gt;
{{Important Note|You can not render model to render target.}}&lt;br /&gt;
This function draws a 3D model - rendered for '''one''' frame. Drawn models are indistinguishable from this one created by &amp;quot;createObject&amp;quot; function. This should be used in conjunction with [[onClientRender]] in order to display continuously. &lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool dxDrawModel( int modelId, float positionX, float positionY, float positionZ, float rotationX, float rotationY, float rotationZ [, float scaleX, float scaleY, float scaleZ ])&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:DxDrawModel3D_at_day.png|thumb|Model during day]]&lt;br /&gt;
[[Image:DxDrawModel3D_at_night.png|thumb|Model during night]]&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
* '''modelId:''' Model you want to draw, must be regular object, you can not draw vehicles and peds&lt;br /&gt;
* '''positionX/Y/Z:''' Position of model&lt;br /&gt;
* '''rotationX/Y/Z:''' Rotation of model&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments===&lt;br /&gt;
* '''scaleX/Y/Z:''' Scale of model, by default {1,1,1}&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns true if the operation was successful, false otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
Simple example&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onClientPreRender&amp;quot;, root, function()&lt;br /&gt;
    dxDrawModel3d(3276, -719.64984, 951.26685, 12.13281, 0, 0,90)&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Drawing_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=File:DxDrawModel3D_at_night.png&amp;diff=78232</id>
		<title>File:DxDrawModel3D at night.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=File:DxDrawModel3D_at_night.png&amp;diff=78232"/>
		<updated>2023-10-14T06:04:36Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=File:DxDrawModel3D_at_day.png&amp;diff=78231</id>
		<title>File:DxDrawModel3D at day.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=File:DxDrawModel3D_at_day.png&amp;diff=78231"/>
		<updated>2023-10-14T06:03:47Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Useful_Functions&amp;diff=77916</id>
		<title>Template:Useful Functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Useful_Functions&amp;diff=77916"/>
		<updated>2023-10-06T16:13:56Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
=== Table functions ===&lt;br /&gt;
*[[addTableChangeHandler]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function monitors the changes of a table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getTableFromSql]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This functionality is used to obtain saved tables using the function ([https://wiki.multitheftauto.com/wiki/SetTableToSql SetTableToSql ]).&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isValueInTable]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns true if the value exists in the table, false if the value does not exist in the table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[pairsByKeys]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function sort pairs table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[rangeToTable]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts a string range to a table containing number values.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setTableProtected]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function protects a table and makes it read-only.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setTableToSql]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function is used to save the table in the database (sql).&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[Sort_Functions]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» These functions are able to sort your tables by a key.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.compare]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks whether two given tables are equal.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.copy]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function copies a whole table and all the tables in that table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.deepmerge]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function deep merges two tables. Every nested table will be correspondingly merged.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.element]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a new table with only userdata content.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.flip]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function flip table values.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.fromString]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts string to a table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.getRandomRows]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns random rows from table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.map]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function goes through a table and replaces every field with the return of the passed function, where the field's value is passed as first argument and optionally more arguments.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.merge]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function merges two or more tables together.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.random]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function retrieves a random value from a table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.removeValue]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function removes a specified value from a table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.size]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the absolute size of a table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[table.toString]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts table to a string.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ACL functions ===&lt;br /&gt;
*[[aclGroupClone]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function clone a group to another group with/without ACLs and/or objects.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getAccountRanks]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function is used to detect the account name groups and put them in the chat.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayerAcls]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of all ACL groups on a player.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayersInACLGroup]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns all players in an ACL group.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPlayerInACL]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a player element is in an ACL group.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[renameAclGroup]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gives an existing ACL group a new name.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPlayerACLAdmin]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a player element belong to Admin group in ACL&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Account functions ===&lt;br /&gt;
*[[getPlayerFromAccountName]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function is used to obtain a player by the name of his account.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Camera functions ===&lt;br /&gt;
*[[smoothMoveCamera]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to create a cinematic camera flight.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Colshape functions ===&lt;br /&gt;
*[[createGarageColShape]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function creates a collision shape from the specified garage.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Cursor functions ===&lt;br /&gt;
*[[getCursorMovedOn]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks in which way the cursor is currently moving.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setCursorCenteredOnRectangle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This functions will center the cursor inside a rectangle.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Drawing functions ===&lt;br /&gt;
*[[dxDrawAnimWindow]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws an animated 2D window on the screen.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawBorderedRectangle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This is a function that will create a bordered rectangle.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawBorderedText]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This is a function that will create a bordered text.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawDashedLine]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a line with dashes.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawGifImage]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function simulates the effect of a GIF image by using image sprites in 2D.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawImage3D]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a 3D image in GTA world.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawImageOnElement]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws an image on any element.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawLinedRectangle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This is a function that will create a rectangle outline with dx lines.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawLoading]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a loading bar on the screen.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawOctagon3D]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function creates a 3D Octagon&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawPolygon]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a custom polygon on the screen.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawProgressBar]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function simulates a progress bar drawed using DirectDraw.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawRectangle3D]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a 3D rectangle in GTA world.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawRectangleOnPlayer]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a 3D rectangle above the player.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawRing]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a ring with dx lines.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawRombo]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function creates a Rhombus.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawSprite]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draw a sprite in the 3D world.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawTextOnElement]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function draws a text on any element.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawTextOnRectangle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Esta funcion crea un rectangle con un texto dentro.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxDrawTriangle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This is a function that will create a triangle with dx lines.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxGetFontSizeFromHeight]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function calculates the font size from given height.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[dxGetRealFontHeight]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function calculates the height of a font.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getScreenStartPositionFromBox]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function helps with getting the correct position for your dx-effects.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[wordWrap]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function breaks a long string into a table of separate lines limited to a specific length in pixels, for drawing separately.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[CreateRectangle3D]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This is a function that will create a 3d rectangle on the player screen.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[DxDrawBordered3DLine]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;»This function creates a bordered area with 3D dx lines.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Effects functions ===&lt;br /&gt;
*[[attachEffect]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you attach an effect to an element.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setScreenFlash]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function will make the screen flash(like a screenshot).&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Element functions === &lt;br /&gt;
*[[autoAttach]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function attaches one element into another at the same position and rotation they are.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[attachElementToBone]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to attach an element to ped bone accurately using new bone functions.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getElementDirectionCardialPoint]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the direction of the element according to the ''wind rose''.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getElementSpeed]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the specified element's speed in m/s, km/h or mph.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getElementUsingData]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns table elements that contains the elements data with the given key and value.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getElementsInDimension]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of elements that are in the specified dimension.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getElementsWithinMarker]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of elements that are within a marker's collision shape.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getNearestElement]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the nearest element (of a specific type) to a player.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementInAir]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if an element is in air or not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementInPhotograph]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if an element is in the player's camera picture area.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementInRange]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to check if an element's range to a main point is within the maximum range.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementMoving]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if an element is moving.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementPlayer]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks whether the element is a player or not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementWithinAColShape]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if an element is within a collision shape element.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[multi_check]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks one element to many, handy and clean.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setElementSpeed]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to set the speed of an element in kph or mph units.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
*[[onPlayerZoneChange]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This code implements an event that is triggered when the player enters a new area on the map.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[onVehicleWeaponFire]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This code implements an event that is triggered when a player in a vehicle fires a vehicle's weapon.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Input functions ===&lt;br /&gt;
*[[bindControlKeys]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to bind each key bound to a control individually. Doing this bypasses a little MTA restriction.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getBoundControls]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of control names that are bound to the specified key.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[unbindControlKeys]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to unbind each key bound to a control individually. Use this function with [[bindControlKeys]].&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isCommandHandlerAdded]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to check if a command is added or not in the respective resource.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Data functions === &lt;br /&gt;
*[[byte2human]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts an integer (number of bytes) into a human-readable unit.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[capitalize]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function capitalizes a given string.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[convertDate]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts date to another look.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[convertServerTickToTimeStamp]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts server ticks to a unix timestamp.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[convertTextToSpeech]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts the provided text to a speech in the provided language which players can hear.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[findRotation3D]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function takes two sets of XYZ coordinates. It returns the 3D direction from point A to point B.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[findRotation]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function takes two points and returns the direction from point A to point B.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[formatDate]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function formats a date on the basis of a format string and returns it.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[formatNumber]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function formats large numbers by adding commas.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[generateRandomASCIIString]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a random string which uses ASCII characters. &amp;lt;/span&amp;gt;&lt;br /&gt;
*[[generateString]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function generates a random string with any characters.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getAge]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function calculates the age of a given birthday.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getDistanceBetweenElements]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Returns the distance between two elements.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getDistanceBetweenPointAndSegment2D]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function takes point coordinates and line (a segment) starting and ending coordinates. It returns the shortest distance between the point and the line.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getEasterDate]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns easter date monthday and month for a given year.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getElementRelatedAngle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the related angle between one element to another. This is useful to check which side an element is to another.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getFreeDimension]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function get free dimension.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getKeyFromValueInTable]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the key of the specified value in a table.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getOffsetFromXYZ]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to take an entity and a position and calculate the relative offset between them accounting for rotations.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPointFromDistanceRotation]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function finds a point based on a starting point, direction and distance.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getRealMonth]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the current month name&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getRGColorFromPercentage]] &amp;lt;span style=&amp;quot;color:gray; font-family:'Georgia', sans-serif; font-size:smaller;&amp;quot;&amp;gt;»This function returns two integers representing red and green colors according to the specified percentage.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getScreenRotationFromWorldPosition]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a screen relative rotation to a world position.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getTimestamp]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the UNIX timestamp of a specified date and time.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[gradientString]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function transforms a string in a new coloured gradient string.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[hex2rgb]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function convert hex to rgb.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[hexColorToRGB]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function convert hex string/number to RGBA values.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isLeapYear]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a boolean representing if a given year is a leap year.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isValidMail]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks whether a provided e-mail string is valid.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[removeHex]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function is used to remove hexadecimal numbers (colors, for example) from strings.&lt;br /&gt;
*[[RGBToHex]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a string representing the color in hexadecimal.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[RGBToHSV]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function convert RGB to HSV color space.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[RGBToDecimal]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function convert RGB to Decimal color.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[secondsToTimeDesc]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts a plain seconds-integer into a user-friendly time description.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[string.count]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function counts the amount of occurences of a string in a string.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[string.explode]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function splits a string at a given separator pattern and returns a table with the pieces.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[string.insert]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function inserts a string within another string at a given position.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[switch]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows the value of a variable or expression to control the flow of program execution via a multiway branch.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[tocolor2rgba]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function convert tocolor to rgba.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[toHex]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts a decimal number to a hexadecimal number, as a fix to be used client-side.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[var dump]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function outputs information about one or more variables using outputConsole.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[wavelengthToRGBA]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts a physical wavelength of light to a RGBA color.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GUI functions === &lt;br /&gt;
*[[centerWindow]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function centers a CEGUI window element responsively in any resolution.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[guiMoveElement]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function moves guiElement by/like using moveObject.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[guiSetStaticImageMovable]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to move a static image like a gui window.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isMouseOnGUICloseButton]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to check whether the mouse cursor/pointer is within a gui-window's native close button.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isMouseOnGuiElement]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to check whether or not your mouse is over a specific gui element, this is especially useful if the gui element has a parent. &amp;lt;/span&amp;gt;&lt;br /&gt;
=====Comboboxes=====&lt;br /&gt;
*[[guiComboBoxAdjustHeight]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function adjusts a CEGUI combobox element to have the correct height.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Gridlists=====&lt;br /&gt;
*[[convertGridListToText]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts grid list contents to text.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getGridListRowIndexFromText]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the GridList row index from the specified text.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[guiGridListAddPlayers]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function add all online players to a grid list.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[guiGridListGetColumnIDFromTitle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets a gridlist's column ID from the column title.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[guiGridListGetSelectedText]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a string containing the inner text of a selected gridlist item.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[guiGridListSetColumnNonSortable]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function makes a gridlist column become non-sortable.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isTextInGridList]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if some text exist or not in the GridList.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=====Labels=====&lt;br /&gt;
*[[guiLabelAddEffect]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function add an effects to the gui-label like (shadow, outline).&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Marker functions ===&lt;br /&gt;
*[[createMarkerAttachedTo]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function creates a marker that is attached to an element.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Math functions ===&lt;br /&gt;
*[[math.clamp]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the number between range of numbers or it's minimum or maximum.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.getBezierPoint]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Get N-th order bezier point.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.hypot]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the Hypotenuse of the triangle given by sides x and y.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.isPointInPolygon]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Check if point is inside polygon or not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.lerp]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Get val between two integer.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.percent]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a percentage from two number values.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.polygonArea]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Compute area of any polygon.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.randomDiff]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Generates a pseudo-random integer that's always different from the last random number generated.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.rotVecToEulerAngle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Rotation Vector To Euler Angle&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.round]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Rounds a number whereas the number of decimals to keep and the method may be set.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[mathNumber]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function is a workaround for the client-side floating-point precision of 24-bits.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[reMap]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Re-maps a number from one range to another.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[Math.percentProgress|math.percentProgress]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Returns a percentage progress from two specific values.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[math.average]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the simple arithmetic mean of multiple numbers.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Map functions ===&lt;br /&gt;
*[[assignLod]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function lets you conveniently generate and apply a LOD model to a mapping object.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getWorldPositionFromMapPosition]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function converts an F11 map position to world position.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ped functions ===&lt;br /&gt;
*[[getAlivePlayers (Client)|getAlivePlayers]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of the alive players client-side.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getAlivePlayersInTeam]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of the alive players in a team.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getGuestPlayers]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets a players not login or players Guest .&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getOnlineAdmins]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of all logged-in administrators.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPedEyesPosition]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to get peds eyes position.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPedGender]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to get peds their gender.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPedMaxHealth]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a pedestrians's maximum health by converting it from their maximum health stat.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPedMaxOxygenLevel]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a ped's maximum oxygen level by converting it from their maximum underwater stamina stat.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPedWeaponSkill]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a ped's corresponding weapon skill level name.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPedHitBone]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets the approximate number of the bone where the ped is hit.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayerFromNamePart]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a player from partial name.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayerFromSerial]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a player from their serial.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayersByData]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of players that have the specified data name.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayersInPhotograph]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of all players in photograph.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayersInVehicles]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of the players insides vehicles from a specified dimension.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPedAiming]]&amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a pedestrian is aiming their weapon.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPedAimingNearPed]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This is similar to isPedAiming but uses a colshape to be more precise.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPedDiving]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This feature checks that pedestrian is diving in the water.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPedDrivingVehicle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a specified pedestrian is driving a vehicle.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPlayerInTeam]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a player is in a specified team.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setPedAttack]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function will make a ped attack a specified target.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setPedFollow]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function will make a ped follow a specified target.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayerNameFromID]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function will get the player name from the ID element data.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Player functions ===&lt;br /&gt;
*[[countPlayersInRange]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the number of players that are within a certain range of the specified coordinates.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayerPreviousAndNextWeapon]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the player previous and next weapon.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getPlayersInRange]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function make a table of players within certain range.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPlayerActuallyInVehicle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a player is actually in a vehicle instead of just in the process of entering.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isPlayerHitByVehicle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function cancels event when a element is hit by a vehicle.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Resource functions ===&lt;br /&gt;
*[[getFilesInResourceFolder]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets a list of files that are inside a folder of a resource.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getResourceScripts]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of the resource scripts.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getResourceSettings]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of the resource settings.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getResourceSize]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the size of a specified resource in kB(kilobyte)&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[refreshResource]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function refreshes your resource if you changed any of the files&lt;br /&gt;
*[[setResourcePriority]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function set resource download priority group.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sound functions ===&lt;br /&gt;
*[[isSoundFinished]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a sound element has finished.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isSoundPlaying]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a sound element is playing or not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[stopSoundSlowly]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function stop your sound element slowly.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Browser functions ===&lt;br /&gt;
*[[playVideo]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function plays a video on the screen.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Team functions ===&lt;br /&gt;
*[[getTeamFromColor]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a team element by the specified color.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getTeamWithFewestPlayers]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a team element with least players of all the specified teams.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Vehicle functions ===&lt;br /&gt;
*[[findEmptyCarSeat]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function finds you the first empty seat in a vehicle.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getNearestVehicle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets the nearest vehicle to the specified player in a specified distance.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getRandomVehicle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets a random vehicle.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getValidVehicleModels]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of all valid vehicle models.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getVehiclesCountByType]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the amount of vehicles by the given type as an integer value.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getVehicleTurnVelocityCenterOfMass]]&amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets a vehicle's turn velocity relative to the vehicle's center or mass.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleDoubleExhaust]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks is exhaust vehicle double.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleEmpty]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks whether a vehicle is empty.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleOccupied]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a specified vehicle is occupied.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleOnRoof]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks whether vehicle is on roof.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleOnFire]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if the vehicle is on fire or not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleReversing]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a specified vehicle is moving backwards.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isVehicleUpgraded]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks is vehicle upgraded by upgrade ID.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setVehicleGravityPoint]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function sets a vehicle's gravity in the direction of a 3 dimensional coordinate with the strength specified.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setVehicleTurnVelocityCenterOfMass]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function sets a vehicle's turn velocity relative to the vehicle's center or mass.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setVehicleHandlingFromText]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function sets a vehicle's handling from text.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[setVehicleWheelModel]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function changes the wheel model of the informed vehicle.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Weapon functions === &lt;br /&gt;
*[[getJetpackWeaponsEnabled]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns a table of enabled weapons usable on a jetpack.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Object functions ===&lt;br /&gt;
*[[getDynamicDoorObjectOpenRatio]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function tells you how open a dynamic door is in a range from 0 to 1.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isElementObject]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function tells you if an element is an object or no.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== XML functions ===&lt;br /&gt;
*[[getXMLNodes]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns all children of a XML node.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Engine functions ===&lt;br /&gt;
*[[engineGetCOLsFromLibrary]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function gets the collision data from the col library.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[engineLoadIMGContainer]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function loads the IMG container.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Utility ===&lt;br /&gt;
*[[animate]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to use interpolateBetween without render event and easily used.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[callClientFunction]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to call any client-side function from the server's side.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[callServerFunction]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to call any server-side function from the client's side.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[check]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if its arguments are of the right type and calls the error-function if one is not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[checkPassiveTimer]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to use passive timers in your conditions. For example you want to prevent players repeatedly using a command.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[coroutine.resume]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function applies a fix for hidden coroutine error messages.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[compact]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function create table containing variables and their values.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getBanFromName]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This functions returns the ban of the given playername.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getCurrentFPS]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the frames per second at which GTA: SA is running.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[getSkinNameFromID]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns the name of the skin from the given id.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[IfElse]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns one of two values based on a boolean expression.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isCharInString]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This shared function allows you to check if a char specified is in a string value.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isLastExecuteInTimer]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function check if the execute is the last execute in the timer.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isMouseInCircle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function checks if a cursor position is in circular area or not.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[isMouseInPosition]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allows you to check whether the mouse cursor/pointer is within a rectangular position.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[iterElements]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function returns ''a time-saving'' iterator for your for-loops.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[PlotTrajectoryAtTime]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» Calculate projectile/water trajectory.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[preprocessor]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function allow you to use gcc macros.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[vector3:compare]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This method checks whether two vectors match, with optional precision.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[svgCreateRoundedRectangle]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function creates a rectangle with rounded edges.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[debounce]] &amp;lt;span style=&amp;quot;color:gray; font-size:smaller;&amp;quot;&amp;gt;» This function is removing unwanted input noise.&amp;lt;/span&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Useful Functions]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Debounce&amp;diff=77915</id>
		<title>Debounce</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Debounce&amp;diff=77915"/>
		<updated>2023-10-06T16:09:34Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;{{Useful Function}} &amp;lt;lowercasetitle&amp;gt;&amp;lt;/lowercasetitle&amp;gt; __NOTOC__ This function  is removing unwanted input noise from buttons, switches or other user input. see: https://www.techtarget.com/whatis/definition/debouncing  ==Syntax== &amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt; void debounce( number timeout, function callback, ...arguments) &amp;lt;/syntaxhighlight&amp;gt;  ==Code== &amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt; &amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt; local debounces = {}  function debounce(timeou...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
&amp;lt;lowercasetitle&amp;gt;&amp;lt;/lowercasetitle&amp;gt;&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function  is removing unwanted input noise from buttons, switches or other user input.&lt;br /&gt;
see: https://www.techtarget.com/whatis/definition/debouncing&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
void debounce( number timeout, function callback, ...arguments)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local debounces = {}&lt;br /&gt;
&lt;br /&gt;
function debounce(timeout, callback, ...)&lt;br /&gt;
    local id = tostring(callback)&lt;br /&gt;
&lt;br /&gt;
    if(isTimer(debounces[id]))then&lt;br /&gt;
        killTimer(debounces[id])&lt;br /&gt;
        debounces[id] = nil;&lt;br /&gt;
    end&lt;br /&gt;
    debounces[id] = setTimer(function(...)&lt;br /&gt;
        callback(...) &lt;br /&gt;
        debounces[id] = nil;&lt;br /&gt;
    end, timeout, 1, ...)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Author:''' CrosRoad95&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Shared&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p style=&amp;quot;color:black;&amp;quot;&amp;gt;This example will ignore first 9 calls and only last one get called within 500ms timeout&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function callback(i)&lt;br /&gt;
    print(i)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
for i=1,10 do&lt;br /&gt;
    debounce(500, callback, i);&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Result in console: 10&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=EngineRequestModel&amp;diff=77585</id>
		<title>EngineRequestModel</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=EngineRequestModel&amp;diff=77585"/>
		<updated>2023-09-03T10:13:16Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Client function}}&lt;br /&gt;
{{New feature/item|3.0158|1.5.7|20147|This function is used to assign the next available model ID to a certain element type.}}&lt;br /&gt;
{{note|Before release '''1.5.8 r20716''' this must be &amp;quot;ped&amp;quot;. After release '''1.5.8 r20716''' this function supports &amp;quot;vehicle&amp;quot; and &amp;quot;object&amp;quot; too.}}&lt;br /&gt;
{{note|Vehicle unique features may be unsupported, see [https://github.com/multitheftauto/mtasa-blue/issues/1861 issue 1861] for examples and details}}&lt;br /&gt;
{{Important Note|Unlike some other functions, the side-effects of this function aren't reverted on resource stop, so you must manually call [[engineFreeModel]] in [[onClientResourceStop]] (Just like the example below does)}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
int engineRequestModel ( string elementType [, int parentID ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''elementType''': &amp;quot;ped&amp;quot;, &amp;quot;object&amp;quot;, &amp;quot;vehicle&amp;quot;, &amp;quot;timed-object&amp;quot;, &amp;quot;clump&amp;quot;&lt;br /&gt;
&lt;br /&gt;
===Optional Arguments=== &lt;br /&gt;
*'''parentID''': The ID of the parent model (by default this is: 1337 - objects, 400 - vehicles, 7 - peds, 3425 - clump models, 4715 - timed objects).&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
{{New feature/item|3.0158|1.5.7|20147| Returns an ''integer'' of the model ID that was available to be assigned to the element type, ''false'' if no free model ID available or invalid element type.}}&lt;br /&gt;
Do not rely on the model numbers returned being consistent across multiple clients or multiple runs of resources. There is no guarantee for the order of the numbers or that the same numbers will always correspond to the same element type. Any patterns are coincidental.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example creates a ped and then gives you the opportunity to change its model. If the resource stops, then the IDs allocated will be deallocated. Use ''/cap'' for creating the ped and ''/sap'' to skin the ped. You will need some skins added to a folder and to the meta.xml for ''/sap'' to work:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local peds = {}&lt;br /&gt;
function createAllocatedPed()&lt;br /&gt;
    local x, y, z = getElementPosition(localPlayer)&lt;br /&gt;
    local id = engineRequestModel(&amp;quot;ped&amp;quot;)&lt;br /&gt;
    peds[id] = createPed(id, x+0.5, y, z+0.5)&lt;br /&gt;
    outputChatBox(&amp;quot;New ped with ID &amp;quot;..id..&amp;quot; created.&amp;quot;)&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;cap&amp;quot;, createAllocatedPed, false, false)&lt;br /&gt;
&lt;br /&gt;
function skinAllocatedPeds()&lt;br /&gt;
    local txd, dff;&lt;br /&gt;
    for id,ped in pairs(peds) do&lt;br /&gt;
        if fileExists(&amp;quot;skins/&amp;quot; .. id .. &amp;quot;.txd&amp;quot;) and fileExists(&amp;quot;skins/&amp;quot; .. id .. &amp;quot;.dff&amp;quot;) then&lt;br /&gt;
            txd = engineLoadTXD(&amp;quot;skins/&amp;quot; .. id .. &amp;quot;.txd&amp;quot;)&lt;br /&gt;
            engineImportTXD(txd, id)&lt;br /&gt;
            dff = engineLoadDFF(&amp;quot;skins/&amp;quot; .. id .. &amp;quot;.dff&amp;quot;)&lt;br /&gt;
            engineReplaceModel(dff, id)&lt;br /&gt;
            outputChatBox(&amp;quot;Model ID &amp;quot;..id..&amp;quot; changed correctly.&amp;quot;)&lt;br /&gt;
        else&lt;br /&gt;
            outputChatBox(&amp;quot;Model ID &amp;quot;..id..&amp;quot; couldn't change. REASON: skins/&amp;quot; .. id .. &amp;quot;.txd or skins/&amp;quot; .. id .. &amp;quot;.dff does not exist.&amp;quot;)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;sap&amp;quot;, skinAllocatedPeds, false, false)&lt;br /&gt;
&lt;br /&gt;
function onStop()&lt;br /&gt;
    for id,ped in pairs(peds) do&lt;br /&gt;
        engineFreeModel(id)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStop&amp;quot;, resourceRoot, onStop)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
{{Requirements|n/a|1.5.7-9.20147|}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Engine functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=DxCreateRenderTarget&amp;diff=77437</id>
		<title>DxCreateRenderTarget</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=DxCreateRenderTarget&amp;diff=77437"/>
		<updated>2023-08-10T16:34:17Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function creates a render target element, which is a special type of [[texture]] that can be drawn on with the dx functions. Successful render target creation is not guaranteed, and may fail due to hardware or memory limitations.&lt;br /&gt;
&lt;br /&gt;
To see if creation is likely to fail, use [[dxGetStatus]]. (When '''VideoMemoryFreeForMTA''' is zero, failure ''is'' guaranteed.)&lt;br /&gt;
{{Tip|Use [[dxSetBlendMode]] to get better quality}}&lt;br /&gt;
{{Tip|It is highly recommended that [[dxSetTestMode]] is used when writing and testing scripts using dxCreateRenderTarget.}}&lt;br /&gt;
{{Note|Render targets are usually cleared when the player minimizes MTA (i.e. alt-tab). See [[onClientRestore]] for details on when to restore any fixed content.}}&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
element dxCreateRenderTarget ( int width, int height [, bool withAlpha = false ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|21938|&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
element dxCreateRenderTarget ( int width, int height, surface-format surfaceFormat )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
}}&lt;br /&gt;
{{OOP||[[Texture|DxRenderTarget]]}}&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''width :''' The width of the texture in pixels.&lt;br /&gt;
*'''height :''' The height of the texture in pixels.&lt;br /&gt;
*'''withAlpha:''' The render target will be created with an alpha channel. 'false' will turn images' alpha channels to black color&lt;br /&gt;
{{Added feature/item|1.6.1|1.6.0|21938|&lt;br /&gt;
*'''surfaceFormat :''' See [[Surface format|Surface formats]]&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns a [[texture]] element if successful, ''false'' if the system is unable to create a render target.&lt;br /&gt;
&lt;br /&gt;
'''You should always check to see if this function has returned false.'''&lt;br /&gt;
&lt;br /&gt;
==Explanation==&lt;br /&gt;
What is a render target?&lt;br /&gt;
&lt;br /&gt;
A render target is like a blank canvas. You can draw on the render target as many times as you like - and even clear it.&lt;br /&gt;
&lt;br /&gt;
If your dxDraw* calls are static (meaning the appearance doesn't change), or only update periodically, then a render target can be useful not only for cleaner code - but for performance reasons too. Instead of making possibly hundreds of dxDraw* calls every frame, you can simply make those calls on a single frame and draw directly to the render target, then use a '''single''' dxDrawImage call every frame afterwards to display the render target.&lt;br /&gt;
&lt;br /&gt;
Render targets can also be used to create and display the same thing multiple times, as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local myRenderTarget&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot,&lt;br /&gt;
    function()&lt;br /&gt;
        myRenderTarget = dxCreateRenderTarget(250, 100, true)       -- Create a render target&lt;br /&gt;
&lt;br /&gt;
        if (myRenderTarget) then &lt;br /&gt;
            updateRenderTarget()     -- Our function to draw to the render target (see below)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
addEventHandler( &amp;quot;onClientRender&amp;quot;, root,&lt;br /&gt;
    function()&lt;br /&gt;
        if myRenderTarget then&lt;br /&gt;
            -- Draw the render target lots of times in different positions on the screen&lt;br /&gt;
            dxDrawImage(350, 50, 250, 100, myRenderTarget)&lt;br /&gt;
            dxDrawImage(450, 380, 250, 100, myRenderTarget)&lt;br /&gt;
            dxDrawImage(550, 250, 250, 100, myRenderTarget)&lt;br /&gt;
            dxDrawImage(650, 70, 250, 100, myRenderTarget)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
function updateRenderTarget()&lt;br /&gt;
    dxSetRenderTarget(myRenderTarget, true)&lt;br /&gt;
    dxSetBlendMode(&amp;quot;modulate_add&amp;quot;)  -- Set 'modulate_add' when drawing stuff on the render target&lt;br /&gt;
&lt;br /&gt;
    dxDrawText(&amp;quot;Hello &amp;quot; .. getTickCount(), 10, 10, 0, 0, tocolor(255, 255, 255, 255), 2, &amp;quot;clear&amp;quot;)        -- Draw a message&lt;br /&gt;
    dxDrawRectangle(10, 50, 40, 40, tocolor(math.random(255), math.random(255), math.random(255)))       -- Draw a square with random color&lt;br /&gt;
&lt;br /&gt;
    -- ... etc, imagine you have a lot of dxDraw* calls to make, this is where render targets come in handy!&lt;br /&gt;
&lt;br /&gt;
    dxSetBlendMode(&amp;quot;blend&amp;quot;)  -- Restore default blending&lt;br /&gt;
    dxSetRenderTarget()      -- Restore default render target&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- We can even update the render target on the fly, by binding it to a key&lt;br /&gt;
bindKey(&amp;quot;r&amp;quot;, &amp;quot;down&amp;quot;, updateRenderTarget)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Drawing_functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:dxCreateRenderTarget]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Surface_format&amp;diff=77436</id>
		<title>Surface format</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Surface_format&amp;diff=77436"/>
		<updated>2023-08-10T16:33:09Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Add surface format page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Based on: https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dformat&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Name&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|r8g8b8&lt;br /&gt;
|	32-bit ARGB pixel format with alpha, using 8 bits per channel.&lt;br /&gt;
|-&lt;br /&gt;
|a8r8g8b8&lt;br /&gt;
|	32-bit ARGB pixel format with alpha, using 8 bits per channel.&lt;br /&gt;
|-&lt;br /&gt;
|x8r8g8b8&lt;br /&gt;
|32-bit RGB pixel format, where 8 bits are reserved for each color.&lt;br /&gt;
|-&lt;br /&gt;
|r5g6b5&lt;br /&gt;
|16-bit RGB pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.&lt;br /&gt;
|-&lt;br /&gt;
|x1r5g5b5&lt;br /&gt;
|16-bit pixel format where 5 bits are reserved for each color.&lt;br /&gt;
|-&lt;br /&gt;
|a1r5g5b5&lt;br /&gt;
|16-bit pixel format where 5 bits are reserved for each color and 1 bit is reserved for alpha.&lt;br /&gt;
|-&lt;br /&gt;
|a4r4g4b4&lt;br /&gt;
|16-bit ARGB pixel format with 4 bits for each channel.&lt;br /&gt;
|-&lt;br /&gt;
|r3g3b2&lt;br /&gt;
|8-bit RGB texture format using 3 bits for red, 3 bits for green, and 2 bits for blue.&lt;br /&gt;
|-&lt;br /&gt;
|a8&lt;br /&gt;
|8-bit alpha only.&lt;br /&gt;
|-&lt;br /&gt;
|a8r3g3b2&lt;br /&gt;
|16-bit ARGB texture format using 8 bits for alpha, 3 bits each for red and green, and 2 bits for blue.&lt;br /&gt;
|-&lt;br /&gt;
|x4r4g4b4&lt;br /&gt;
|16-bit RGB pixel format using 4 bits for each color.&lt;br /&gt;
|-&lt;br /&gt;
|a2b10g10r10&lt;br /&gt;
|32-bit pixel format using 10 bits for each color and 2 bits for alpha.&lt;br /&gt;
|-&lt;br /&gt;
|a8b8g8r8&lt;br /&gt;
|32-bit ARGB pixel format with alpha, using 8 bits per channel.&lt;br /&gt;
|-&lt;br /&gt;
|x8b8g8r8&lt;br /&gt;
|32-bit RGB pixel format, where 8 bits are reserved for each color.&lt;br /&gt;
|-&lt;br /&gt;
|g16r16&lt;br /&gt;
|32-bit pixel format using 16 bits each for green and red.&lt;br /&gt;
|-&lt;br /&gt;
|a2r10g10b10&lt;br /&gt;
|32-bit pixel format using 10 bits each for red, green, and blue, and 2 bits for alpha.&lt;br /&gt;
|-&lt;br /&gt;
|a16b16g16r16&lt;br /&gt;
|64-bit pixel format using 16 bits for each component.&lt;br /&gt;
|-&lt;br /&gt;
|a8p8&lt;br /&gt;
|8-bit color indexed with 8 bits of alpha.&lt;br /&gt;
|-&lt;br /&gt;
|p8&lt;br /&gt;
|8-bit color indexed.&lt;br /&gt;
|-&lt;br /&gt;
|l8&lt;br /&gt;
|8-bit luminance only.&lt;br /&gt;
|-&lt;br /&gt;
|l16&lt;br /&gt;
|16-bit luminance only.&lt;br /&gt;
|-&lt;br /&gt;
|a8l8&lt;br /&gt;
|16-bit using 8 bits each for alpha and luminance.&lt;br /&gt;
|-&lt;br /&gt;
|r8g8b8&lt;br /&gt;
|24-bit RGB pixel format with 8 bits per channel.&lt;br /&gt;
|-&lt;br /&gt;
|a4l4&lt;br /&gt;
|8-bit using 4 bits each for alpha and luminance.&lt;br /&gt;
|-&lt;br /&gt;
|r16f&lt;br /&gt;
|16-bit float format using 16 bits for the red channel.&lt;br /&gt;
|-&lt;br /&gt;
|g16r16f&lt;br /&gt;
|32-bit float format using 16 bits for the red channel and 16 bits for the green channel.&lt;br /&gt;
|-&lt;br /&gt;
|a16b16g16r16f&lt;br /&gt;
|64-bit float format using 16 bits for the each channel (alpha, blue, green, red).&lt;br /&gt;
|-&lt;br /&gt;
|r32f&lt;br /&gt;
|32-bit float format using 32 bits for the red channel.&lt;br /&gt;
|-&lt;br /&gt;
|g32r32f&lt;br /&gt;
|64-bit float format using 32 bits for the red channel and 32 bits for the green channel.&lt;br /&gt;
|-&lt;br /&gt;
|a32b32g32r32f&lt;br /&gt;
|128-bit float format using 32 bits for the each channel (alpha, blue, green, red).&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=ReloadBrowserPage&amp;diff=77422</id>
		<title>ReloadBrowserPage</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=ReloadBrowserPage&amp;diff=77422"/>
		<updated>2023-08-09T14:27:29Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: add missing &amp;quot;ignoreCache&amp;quot; argument&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Client function}}&lt;br /&gt;
{{New feature/item|3.0153|1.5.3|9912|&lt;br /&gt;
This function reloads the current browser's page.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool reloadBrowserPage( browser webBrowser [, bool ignoreCache ] )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
*'''webBrowser:''' The browser that you want to reload.&lt;br /&gt;
*'''ignoreCache :''' Ignoring cached content, Equivalent to &amp;quot;Shift + F5&amp;quot; in most browsers&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the browser has reloaded, ''false'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example creates a browser that can return to the last and previous pages and can also be refreshed:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
window = guiCreateWindow(126, 122, 848, 674, &amp;quot;Firechrome&amp;quot;, false)&lt;br /&gt;
guiWindowSetSizable(window, false)&lt;br /&gt;
&lt;br /&gt;
navigateBackBtn = guiCreateButton(10, 19, 39, 36, &amp;quot;&amp;lt;&amp;quot;, false, window)&lt;br /&gt;
navigateForwardBtn = guiCreateButton(98, 19, 39, 36, &amp;quot;&amp;gt;&amp;quot;, false, window)&lt;br /&gt;
addressBar =  guiCreateEdit(137, 19, 701, 36, &amp;quot;&amp;quot;, false, window)&lt;br /&gt;
guiSetEnabled( addressBar, false )&lt;br /&gt;
reloadBtn = guiCreateButton(49, 19, 49, 36, &amp;quot;reload&amp;quot;, false, window)&lt;br /&gt;
browser = guiCreateBrowser(10, 55, 828, 609, false, false, false, window)&lt;br /&gt;
&lt;br /&gt;
-- Load our page on browser creation.&lt;br /&gt;
local theBrowser = guiGetBrowser(browser) &lt;br /&gt;
addEventHandler(&amp;quot;onClientBrowserCreated&amp;quot;, theBrowser, &lt;br /&gt;
    function()&lt;br /&gt;
        loadBrowserURL(source, &amp;quot;https://forum.mtasa.com/&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
-- This checks to see if the browser can navigate in any direction and enables the back or forward buttons&lt;br /&gt;
addEventHandler( &amp;quot;onClientBrowserDocumentReady&amp;quot;, theBrowser, function( )&lt;br /&gt;
    navigateForwardBtn.enabled = (canBrowserNavigateForward(theBrowser))&lt;br /&gt;
    navigateBackBtn.enabled = (canBrowserNavigateBack(theBrowser))&lt;br /&gt;
    guiSetText( addressBar, getBrowserURL( theBrowser ) )&lt;br /&gt;
end )&lt;br /&gt;
&lt;br /&gt;
-- This part handles the GUI navigation buttons for the browser.&lt;br /&gt;
addEventHandler( &amp;quot;onClientGUIClick&amp;quot;, resourceRoot, function ( )&lt;br /&gt;
    if source == navigateBackBtn then&lt;br /&gt;
        navigateBrowserBack(theBrowser)&lt;br /&gt;
    elseif source == navigateForwardBtn then&lt;br /&gt;
        navigateBrowserForward(theBrowser)&lt;br /&gt;
    elseif source == reloadBtn then&lt;br /&gt;
        reloadBrowserPage(theBrowser)&lt;br /&gt;
    end&lt;br /&gt;
end )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{CEF_functions}}&lt;br /&gt;
&lt;br /&gt;
[[hu:reloadBrowserPage]]&lt;br /&gt;
[[RO:reloadBrowserPage]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Math.lerp&amp;diff=76282</id>
		<title>Math.lerp</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Math.lerp&amp;diff=76282"/>
		<updated>2023-03-12T06:02:10Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: add variant of mathlerp that doesn't care about order of number&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;int math.lerp(int from, int to, int val)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
* '''val''': The number from 0 to 1&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns a number if everything went good, ''to'' otherwise.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- Where b must be greater than a&lt;br /&gt;
function math.lerp(a, b, k)&lt;br /&gt;
	local result = a * (1-k) + b * k&lt;br /&gt;
	if result &amp;gt;= b then&lt;br /&gt;
		result = b&lt;br /&gt;
	elseif result &amp;lt;= a then&lt;br /&gt;
		result = a&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function math.lerp(a, b, k)&lt;br /&gt;
	if(a &amp;gt; b)then&lt;br /&gt;
		local _a = a;&lt;br /&gt;
		a = b;&lt;br /&gt;
		b = _a;&lt;br /&gt;
	end&lt;br /&gt;
	local result = a * (1-k) + b * k&lt;br /&gt;
	if result &amp;gt;= b then&lt;br /&gt;
		result = b&lt;br /&gt;
	elseif result &amp;lt;= a then&lt;br /&gt;
		result = a&lt;br /&gt;
	end&lt;br /&gt;
	return result&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
math.lerp(100, 250, 0.5)&lt;br /&gt;
-- Returns: 175&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetPointFromDistanceRotation&amp;diff=76281</id>
		<title>GetPointFromDistanceRotation</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetPointFromDistanceRotation&amp;diff=76281"/>
		<updated>2023-03-11T17:38:49Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Remove unnecessary new lines&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Function}}&lt;br /&gt;
&amp;lt;lowercasetitle&amp;gt;&amp;lt;/lowercasetitle&amp;gt;&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function takes a set of XY coordinates, a distance and a rotation argument. It returns XY coordinates of the point that is the given distance away from the given point, in the given direction.&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;float, float getPointFromDistanceRotation(float x, float y, float dist, float angle)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Required Arguments===&lt;br /&gt;
* '''x''': The X coordinate of the starting point.&lt;br /&gt;
* '''y''': The Y coordinate of the starting point.&lt;br /&gt;
* '''dist''': The distance from the starting point to the target point.&lt;br /&gt;
* '''angle''': The direction from the starting point to the target point.&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Function source&amp;quot; class=&amp;quot;both&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function getPointFromDistanceRotation(x, y, dist, angle)&lt;br /&gt;
    local a = math.rad(90 - angle);&lt;br /&gt;
    local dx = math.cos(a) * dist;&lt;br /&gt;
    local dy = math.sin(a) * dist;&lt;br /&gt;
    return x+dx, y+dy;&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This command surrounds a player with peds.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addCommandHandler(&amp;quot;surround&amp;quot;,&lt;br /&gt;
function (player)&lt;br /&gt;
&lt;br /&gt;
  local x,y,z = getElementPosition(player);&lt;br /&gt;
&lt;br /&gt;
  for i=1, 8 do&lt;br /&gt;
    local newX, newY = getPointFromDistanceRotation(x, y, 2, 360 * (i/8));&lt;br /&gt;
    createPed(10, newX, newY, z)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Author: robhol.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Useful_Functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Vehicle_Upgrades&amp;diff=71986</id>
		<title>Vehicle Upgrades</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Vehicle_Upgrades&amp;diff=71986"/>
		<updated>2021-08-28T15:26:50Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: typo, should be Stratum not Statum&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{|  class=&amp;quot;wikitable sortable&amp;quot; style=&amp;quot;width:100%;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| ID&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Modelname&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Part&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1000''' || spl_b_mar_m || Spoiler || Pro || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1001''' || spl_b_bab_m || Spoiler || Win || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1002''' || spl_b_bar_m || Spoiler || Drag || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1003''' || spl_b_mab_m || Spoiler || Alpha || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1004''' || bnt_b_sc_m || Vents || Champ Scoop || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1005''' || bnt_b_sc_l || Vents || Fury Scoop || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1006''' || rf_b_sc_r || Roof || Roof Scoop || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1007''' || wg_l_b_ssk || Sideskirt || Right Sideskirt || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1008''' || nto_b_l || Nitro || 5 times || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1009''' || nto_b_s || Nitro || 2 times || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1010''' || nto_b_tw || Nitro || 10 times || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1011''' || bnt_b_sc_p_m || Vents || Race Scoop || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1012''' || bnt_b_sc_p_l || Vents || Worx Scoop || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1013''' || lgt_b_rspt || Lamps || Round Fog || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1014''' || spl_b_bar_l || Spoiler || Champ || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1015''' || spl_b_bbr_l || Spoiler || Race || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1016''' || spl_b_bbr_m || Spoiler || Worx || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1017''' || wg_r_b_ssk || Sideskirt || Left Sideskirt || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1018''' || exh_b_ts || Exhaust || Upswept || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1019''' || exh_b_t || Exhaust || Twin || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1020''' || exh_b_l || Exhaust || Large || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1021''' || exh_b_m || Exhaust || Medium || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1022''' || exh_b_s || Exhaust || Small || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1023''' || spl_b_bbb_m || Spoiler || Fury || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1024''' || lgt_b_sspt || Lamps || Square Fog || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1025''' || wheel_or1 || Wheels || Offroad || Certain Transfender cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1026''' || wg_l_a_s || Sideskirt || Right Alien Sideskirt || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1027''' || wg_r_a_s || Sideskirt || Left Alien Sideskirt || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1028''' || exh_a_s || Exhaust || Alien || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1029''' || exh_c_s || Exhaust || X-Flow || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1030''' || wg_r_c_s || Sideskirt || Left X-Flow Sideskirt || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1031''' || wg_l_c_s || Sideskirt || Right X-Flow Sideskirt || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1032''' || rf_a_s || Roof || Alien Roof Vent || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1033''' || rf_c_s || Roof || X-Flow Roof Vent || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1034''' || exh_a_l || Exhaust || Alien || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1035''' || rf_c_l || Roof || X-Flow Roof Vent || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1036''' || wg_l_a_l || SideSkirt || Right Alien Sideskirt || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1037''' || exh_c_l || Exhaust || X-Flow || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1038''' || rf_a_l || Roof || Alien Roof Vent || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1039''' || wg_l_c_l || SideSkirt || Left X-Flow Sideskirt || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1040''' || wg_r_a_l || SideSkirt || Left Alien Sideskirt || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1041''' || wg_r_c_l || SideSkirt || Right X-Flow Sideskirt || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1042''' || wg_l_lr_br1 || SideSkirt || Right Chrome Sideskirt || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1043''' || exh_lr_br2 || Exhaust || Slamin || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1044''' || exh_lr_br1 || Exhaust || Chrome || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1045''' || exh_c_f || Exhaust || X-Flow || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1046''' || exh_a_f || Exhaust || Alien || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1047''' || wg_l_a_f || SideSkirt || Right Alien Sideskirt || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1048''' || wg_l_c_f || SideSkirt || Right X-Flow Sideskirt || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1049''' || spl_a_f_r || Spoiler || Alien || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1050''' || spl_c_f_r || Spoiler || X-Flow || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1051''' || wg_r_a_f || SideSkirt || Left Alien Sideskirt || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1052''' || wg_r_c_f || SideSkirt || Left X-Flow Sideskirt || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1053''' || rf_c_f || Roof || X-Flow || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1054''' || rf_a_f || Roof || Alien || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1055''' || rf_a_st || Roof || Alien || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1056''' || wg_l_a_st || Sideskirt || Right Alien Sideskirt || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1057''' || wg_l_c_st || Sideskirt || Right X-Flow Sideskirt || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1058''' || spl_a_st_r || Spoiler || Alien || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1059''' || exh_c_st || Exhaust || X-Flow || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1060''' || spl_c_st_r || Spoiler || X-Flow || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1061''' || rf_c_st || Roof || X-Flow || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1062''' || wg_r_a_st || Sideskirt || Left Alien Sideskirt || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1063''' || wg_r_c_st || Sideskirt || Left X-Flow Sideskirt || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1064''' || exh_a_st || Exhaust || Alien || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1065''' || exh_a_j || Exhaust || Alien || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1066''' || exh_c_j || Exhaust || X-Flow || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1067''' || rf_a_j || Roof || Alien || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1068''' || rf_c_j || Roof || X-Flow || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1069''' || wg_l_a_j || Sideskirt || Right Alien Sideskirt || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1070''' || wg_l_c_j || Sideskirt || Right X-Flow Sideskirt || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1071''' || wg_r_a_j || Sideskirt || Left Alien Sideskirt || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1072''' || wg_r_c_j || Sideskirt || Left X-Flow Sideskirt || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1073''' || wheel_sr6 || Wheels || Shadow || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1074''' || wheel_sr3 || Wheels || Mega || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1075''' || wheel_sr2 || Wheels || Rimshine || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1076''' || wheel_lr4 || Wheels || Wires || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1077''' || wheel_lr1 || Wheels || Classic || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1078''' || wheel_lr3 || Wheels || Twist || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1079''' || wheel_sr1 || Wheels || Cutter || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1080''' || wheel_sr5 || Wheels || Switch || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1081''' || wheel_sr4 || Wheels || Grove || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1082''' || wheel_gn1 || Wheels || Import || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1083''' || wheel_lr2 || Wheels || Dollar || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1084''' || wheel_lr5 || Wheels || Trance || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1085''' || wheel_gn2 || Wheels || Atomic || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1086''' || stereo || Stereo || Stereo || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1087''' || hydralics || Hydraulics || Hydraulics || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1088''' || rf_a_u || Roof || Alien || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1089''' || exh_c_u || Exhaust || X-Flow || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1090''' || wg_l_a_u || Sideskirt || Right Alien Sideskirt || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1091''' || rf_c_u || Roof || X-Flow || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1092''' || exh_a_u || Exhaust || Alien || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1093''' || wg_l_c_u || Sideskirt || Right X-Flow Sideskirt || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1094''' || wg_r_a_u || Sideskirt || Left Alien Sideskirt || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1095''' || wg_r_c_u || Sideskirt || Right X-Flow Sideskirt || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1096''' || wheel_gn3 || Wheels || Ahab || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1097''' || wheel_gn4 || Wheels || Virtual || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1098''' || wheel_gn5 || Wheels || Access || Most cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1099''' || wg_r_lr_br1 || Sideskirt || Left Chrome Sideskirt || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1100''' || misc_c_lr_rem1 || Bullbar || Chrome Grill || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1101''' || wg_r_lr_rem1 || Sideskirt || Left `Chrome Flames` Sideskirt || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1102''' || wg_r_lr_sv || Sideskirt || Left `Chrome Strip` Sideskirt || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1103''' || rf_lr_bl2 || Roof || Covertible || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1104''' || exh_lr_bl1 || Exhaust || Chrome || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1105''' || exh_lr_bl2 || Exhaust || Slamin || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1106''' || wg_l_lr_rem2 || Sideskirt || Right `Chrome Arches` || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1107''' || wg_r_lr_bl1 || Sideskirt || Left `Chrome Strip` Sideskirt || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1108''' || wg_l_lr_bl1 || Sideskirt || Right `Chrome Strip` Sideskirt || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1109''' || bbb_lr_slv1 || Rear Bullbars || Chrome || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1110''' || bbb_lr_slv2 || Rear Bullbars || Slamin || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1111''' || bnt_lr_slv1 || Front Sign? || Little Sign? || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1112''' || bnt_lr_slv2 || Front Sign? || Little Sign? || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1113''' || exh_lr_slv1 || Exhaust || Chrome || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1114''' || exh_lr_slv2 || Exhaust || Slamin || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1115''' || fbb_lr_slv1 || Front Bullbars || Chrome || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1116''' || fbb_lr_slv2 || Front Bullbars || Slamin || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1117''' || fbmp_lr_slv1 || Front Bumper || Chrome || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1118''' || wg_l_lr_slv1 || Sideskirt || Right `Chrome Trim` Sideskirt || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1119''' || wg_l_lr_slv2 || Sideskirt || Right `Wheelcovers` Sideskirt || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1120''' || wg_r_lr_slv1 || Sideskirt || Left `Chrome Trim` Sideskirt || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1121''' || wg_r_lr_slv2 || Sideskirt || Left `Wheelcovers` Sideskirt || Slamvan&lt;br /&gt;
|-&lt;br /&gt;
| '''1122''' || wg_l_lr_rem1 || Sideskirt || Right `Chrome Flames` Sideskirt || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1123''' || misc_c_lr_rem2 || Bullbars || Bullbar Chrome Bars || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1124''' || wg_r_lr_rem2 || Sideskirt || Left `Chrome Arches` Sideskirt || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1125''' || misc_c_lr_rem3 || Bullbars || Bullbar Chrome Lights || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1126''' || exh_lr_rem1 || Exhaust || Chrome Exhaust || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1127''' || exh_lr_rem2 || Exhaust || Slamin Exhaust || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1128''' || rf_lr_bl1 || Roof || Vinyl Hardtop || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1129''' || exh_lr_sv1 || Exhaust || Chrome || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1130''' || rf_lr_sv1 || Roof || Hardtop || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1131''' || rf_lr_sv2 || Roof || Softtop || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1132''' || exh_lr_sv2 || Exhaust || Slamin || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1133''' || wg_l_lr_sv || Sideskirt || Right `Chrome Strip` Sideskirt || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1134''' || wg_l_lr_t1 || SideSkirt || Right `Chrome Strip` Sideskirt || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1135''' || exh_lr_t2 || Exhaust || Slamin || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1136''' || exh_lr_t1 || Exhaust || Chrome || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1137''' || wg_r_lr_t1 || Sideskirt || Left `Chrome Strip` Sideskirt || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1138''' || spl_a_s_b || Spoiler || Alien || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1139''' || spl_c_s_b || Spoiler || X-Flow || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1140''' || rbmp_c_s || Rear Bumper || X-Flow || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1141''' || rbmp_a_s || Rear Bumper || Alien || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1142''' || bntr_b_ov || Hood || Left Oval Hoods || Certain Transfender Cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1143''' || bntl_b_ov || Hood || Right Oval Hoods || Certain Transfender Cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1144''' || bntr_b_sq || Hood || Left Square Hoods || Certain Transfender Cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1145''' || bntl_b_sq || Hood || Right Square Hoods || Certain Transfender Cars&lt;br /&gt;
|-&lt;br /&gt;
| '''1146''' || spl_c_l_b || Spoiler || X-Flow || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1147''' || spl_a_l_b || Spoiler || Alien || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1148''' || rbmp_c_l || Rear Bumper || X-Flow || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1149''' || rbmp_a_l || Rear Bumper || Alien || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1150''' || rbmp_a_f || Rear Bumper || Alien || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1151''' || rbmp_c_f || Rear Bumper || X-Flow || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1152''' || fbmp_c_f || Front Bumper || X-Flow || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1153''' || fbmp_a_f || Front Bumper || Alien || Flash&lt;br /&gt;
|-&lt;br /&gt;
| '''1154''' || rbmp_a_st || Rear Bumper || Alien || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1155''' || fbmp_a_st || Front Bumper || Alien || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1156''' || rbmp_c_st || Rear Bumper || X-Flow || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1157''' || fbmp_c_st || Front Bumper || X-Flow || Stratum&lt;br /&gt;
|-&lt;br /&gt;
| '''1158''' || spl_c_j_b || Spoiler || X-Flow || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1159''' || rbmp_a_j || Rear Bumper || Alien || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1160''' || fbmp_a_j || Front Bumper || Alien || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1161''' || rbmp_c_j || Rear Bumper || X-Flow || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1162''' || spl_a_j_b || Spoiler || Alien || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1163''' || spl_c_u_b || Spoiler || X-Flow || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1164''' || spl_a_u_b || Spoiler || Alien || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1165''' || fbmp_c_u || Front Bumper || X-Flow || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1166''' || fbmp_a_u || Front Bumper || Alien || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1167''' || rbmp_c_u || Rear Bumper || X-Flow || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1168''' || rbmp_a_u || Rear Bumper || Alien || Uranus&lt;br /&gt;
|-&lt;br /&gt;
| '''1169''' || fbmp_a_s || Front Bumper || Alien || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1170''' || fbmp_c_s || Front Bumper || X-Flow || Sultan&lt;br /&gt;
|-&lt;br /&gt;
| '''1171''' || fbmp_a_l || Front Bumper || Alien || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1172''' || fbmp_c_l || Front Bumper || X-Flow || Elegy&lt;br /&gt;
|-&lt;br /&gt;
| '''1173''' || fbmp_c_j || Front Bumper || X-Flow || Jester&lt;br /&gt;
|-&lt;br /&gt;
| '''1174''' || fbmp_lr_br1 || Front Bumper || Chrome || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1175''' || fbmp_lr_br2 || Rear Bumper || Slamin || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1176''' || rbmp_lr_br1 || Front Bumper || Chrome || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1177''' || rbmp_lr_br2 || Rear Bumper || Slamin || Broadway&lt;br /&gt;
|-&lt;br /&gt;
| '''1178''' || rbmp_lr_rem2 || Rear Bumper || Slamin || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1179''' || fbmp_lr_rem1 || Front Bumper || Chrome || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1180''' || rbmp_lr_rem1 || Rear Bumper || Chrome || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1181''' || fbmp_lr_bl2 || Front Bumper || Slamin || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1182''' || fbmp_lr_bl1 || Front Bumper || Chrome || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1183''' || rbmp_lr_bl2 || Rear Bumper || Slamin || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1184''' || rbmp_lr_bl1 || Rear Bumper || Chrome || Blade&lt;br /&gt;
|-&lt;br /&gt;
| '''1185''' || fbmp_lr_rem2 || Front Bumper || Slamin || Remington&lt;br /&gt;
|-&lt;br /&gt;
| '''1186''' || rbmp_lr_sv2 || Rear Bumper || Slamin || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1187''' || rbmp_lr_sv1 || Rear Bumper || Chrome || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1188''' || fbmp_lr_sv2 || Front Bumper || Slamin || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1189''' || fbmp_lr_sv1 || Front Bumper || Chrome || Savanna&lt;br /&gt;
|-&lt;br /&gt;
| '''1190''' || fbmp_lr_t2 || Front Bumper || Slamin || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1191''' || fbmp_lr_t1 || Front Bumper || Chrome || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1192''' || rbmp_lr_t1 || Rear Bumper || Chrome || Tornado&lt;br /&gt;
|-&lt;br /&gt;
| '''1193''' || rbmp_lr_t2 || Rear Bumper || Slamin || Tornado&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==All valid upgrades per vehicle==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:8%;&amp;quot;| Name&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:2%;&amp;quot;| ID&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; style=&amp;quot;width:50%;&amp;quot;| Component ID&lt;br /&gt;
|-&lt;br /&gt;
|'''Landstalker'''||400|| 1008, 1009, 1010, 1013, 1018, 1019, 1020, 1021, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Bravura'''||401|| 1001, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1146, 1147, 1158, 1162, 1163&lt;br /&gt;
|-&lt;br /&gt;
|'''Buffalo'''||402|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Linerunner'''||403|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Perrenial'''||404|| 1000, 1002, 1007, 1008, 1009, 1010, 1013, 1016, 1017, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Sentinel'''||405|| 1000, 1001, 1008, 1009, 1010, 1014, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Dumper'''||406|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Firetruck'''||407|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Trashmaster'''||408|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Stretch'''||409|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Manana'''||410|| 1001, 1003, 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1021, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Infernus'''||411|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Voodoo'''||412|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Pony'''||413|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Mule'''||414|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Cheetah'''||415|| 1001, 1003, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Ambulance'''||416|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Leviathan'''||417|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Moonbeam'''||418|| 1002, 1006, 1008, 1009, 1010, 1016, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Esperanto'''||419|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Taxi'''||420|| 1001, 1003, 1004, 1005, 1008, 1009, 1010, 1019, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Washington'''||421|| 1000, 1008, 1009, 1010, 1014, 1016, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Bobcat'''||422|| 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Mr Whoopee'''||423|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''BF Injection'''||424|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hunter'''||425|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Premier'''||426|| 1001, 1003, 1004, 1005, 1006, 1008, 1009, 1010, 1019, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Enforcer'''||427|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Securicar'''||428|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Banshee'''||429|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Predator'''||430&lt;br /&gt;
|-&lt;br /&gt;
|'''Bus'''||431|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Rhino'''||432|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Barracks'''||433|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hotknife'''||434|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Trailer 1'''||435|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Previon'''||436|| 1001, 1003, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1021, 1022, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Coach'''||437|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Cabbie'''||438|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Stallion'''||439|| 1001, 1003, 1007, 1008, 1009, 1010, 1013, 1017, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Rumpo'''||440|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''RC Bandit'''||441|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Romero'''||442|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Packer'''||443|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Monster'''||444|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Admiral'''||445|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Squalo'''||446&lt;br /&gt;
|-&lt;br /&gt;
|'''Seasparrow'''||447|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Pizzaboy'''||448&lt;br /&gt;
|-&lt;br /&gt;
|'''Tram'''||449&lt;br /&gt;
|-&lt;br /&gt;
|'''Trailer 2'''||450|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Turismo'''||451|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Speeder'''||452&lt;br /&gt;
|-&lt;br /&gt;
|'''Reefer'''||453&lt;br /&gt;
|-&lt;br /&gt;
|'''Tropic'''||454&lt;br /&gt;
|-&lt;br /&gt;
|'''Flatbed'''||455|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Yankee'''||456|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Caddy'''||457|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Solair'''||458|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Berkley's RC Van'''||459|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Skimmer'''||460|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''PCJ-600'''||461&lt;br /&gt;
|-&lt;br /&gt;
|'''Faggio'''||462&lt;br /&gt;
|-&lt;br /&gt;
|'''Freeway'''||463&lt;br /&gt;
|-&lt;br /&gt;
|'''RC Baron'''||464|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''RC Raider'''||465|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Glendale'''||466|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Oceanic'''||467|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Sanchez'''||468&lt;br /&gt;
|-&lt;br /&gt;
|'''Sparrow'''||469|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Patriot'''||470|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Quad'''||471|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Coastguard'''||472&lt;br /&gt;
|-&lt;br /&gt;
|'''Dinghy'''||473&lt;br /&gt;
|-&lt;br /&gt;
|'''Hermes'''||474|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Sabre'''||475|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Rustler'''||476|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''ZR-350'''||477|| 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Walton'''||478|| 1004, 1005, 1008, 1009, 1010, 1012, 1013, 1020, 1021, 1022, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Regina'''||479|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Comet'''||480|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''BMX'''||481&lt;br /&gt;
|-&lt;br /&gt;
|'''Burrito'''||482|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Camper'''||483|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Marquis'''||484&lt;br /&gt;
|-&lt;br /&gt;
|'''Baggage'''||485|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Dozer'''||486|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Maverick'''||487|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''News Chopper'''||488|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Rancher'''||489|| 1000, 1002, 1004, 1005, 1006, 1008, 1009, 1010, 1013, 1016, 1018, 1019, 1020, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''FBI Rancher'''||490|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Virgo'''||491|| 1003, 1007, 1008, 1009, 1010, 1014, 1017, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Greenwood'''||492|| 1000, 1004, 1005, 1006, 1008, 1009, 1010, 1016, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Jetmax'''||493&lt;br /&gt;
|-&lt;br /&gt;
|'''Hotring'''||494|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Sandking'''||495|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Blista Compact'''||496|| 1001, 1002, 1003, 1006, 1007, 1008, 1009, 1010, 1011, 1017, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143&lt;br /&gt;
|-&lt;br /&gt;
|'''Police Maverick'''||497|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Boxville'''||498|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Benson'''||499|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Mesa'''||500|| 1008, 1009, 1010, 1013, 1019, 1020, 1021, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''RC Goblin'''||501|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hotring Racer A'''||502|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hotring Racer B'''||503|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Bloodring Banger'''||504|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Rancher'''||505|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Super GT'''||506|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Elegant'''||507|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Journey'''||508|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Bike'''||509&lt;br /&gt;
|-&lt;br /&gt;
|'''Mountain Bike'''||510&lt;br /&gt;
|-&lt;br /&gt;
|'''Beagle'''||511|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Cropdust'''||512|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Stunt'''||513|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Tanker'''||514|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Roadtrain'''||515|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Nebula'''||516|| 1000, 1002, 1004, 1007, 1008, 1009, 1010, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Majestic'''||517|| 1002, 1003, 1007, 1008, 1009, 1010, 1016, 1017, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Buccaneer'''||518|| 1001, 1003, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1018, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Shamal'''||519|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hydra'''||520|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''FCR-900'''||521&lt;br /&gt;
|-&lt;br /&gt;
|'''NRG-500'''||522&lt;br /&gt;
|-&lt;br /&gt;
|'''HPV1000'''||523&lt;br /&gt;
|-&lt;br /&gt;
|'''Cement Truck'''||524|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Tow Truck'''||525|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Fortune'''||526|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Cadrona'''||527|| 1001, 1007, 1008, 1009, 1010, 1014, 1015, 1017, 1018, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''FBI Truck'''||528|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Willard'''||529|| 1001, 1003, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1017, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Forklift'''||530|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Tractor'''||531|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Combine'''||532|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Feltzer'''||533|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Remington'''||534|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1100, 1101, 1106, 1122, 1123, 1124, 1125, 1126, 1127, 1178, 1179, 1180, 1185&lt;br /&gt;
|-&lt;br /&gt;
|'''Slamvan'''||535|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1109, 1110, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121&lt;br /&gt;
|-&lt;br /&gt;
|'''Blade'''||536|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1103, 1104, 1105, 1107, 1108, 1128, 1181, 1182, 1183, 1184&lt;br /&gt;
|-&lt;br /&gt;
|'''Freight'''||537&lt;br /&gt;
|-&lt;br /&gt;
|'''Streak'''||538&lt;br /&gt;
|-&lt;br /&gt;
|'''Vortex'''||539|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Vincent'''||540|| 1001, 1004, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1020, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Bullet'''||541|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Clover'''||542|| 1008, 1009, 1010, 1014, 1015, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Sadler'''||543|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Firetruck LA'''||544|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hustler'''||545|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Intruder'''||546|| 1001, 1002, 1004, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Primo'''||547|| 1000, 1003, 1008, 1009, 1010, 1016, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143&lt;br /&gt;
|-&lt;br /&gt;
|'''Cargobob'''||548|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Tampa'''||549|| 1001, 1003, 1007, 1008, 1009, 1010, 1011, 1012, 1017, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Sunrise'''||550|| 1001, 1003, 1004, 1005, 1006, 1008, 1009, 1010, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Merit'''||551|| 1002, 1003, 1005, 1006, 1008, 1009, 1010, 1016, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Utility'''||552|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Nevada'''||553|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Yosemite'''||554|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Windsor'''||555|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Monster A'''||556|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Monster B'''||557|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Uranus'''||558|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1163, 1164, 1165, 1166, 1167, 1168&lt;br /&gt;
|-&lt;br /&gt;
|'''Jester'''||559|| 1008, 1009, 1010, 1025, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1158, 1159, 1160, 1161, 1162, 1173&lt;br /&gt;
|-&lt;br /&gt;
|'''Sultan'''||560|| 1008, 1009, 1010, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1138, 1139, 1140, 1141, 1169, 1170&lt;br /&gt;
|-&lt;br /&gt;
|'''Stratum'''||561|| 1008, 1009, 1010, 1025, 1026, 1027, 1030, 1031, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1154, 1155, 1156, 1157&lt;br /&gt;
|-&lt;br /&gt;
|'''Elegy'''||562|| 1008, 1009, 1010, 1025, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1146, 1147, 1148, 1149, 1171, 1172&lt;br /&gt;
|-&lt;br /&gt;
|'''Raindance'''||563|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''RC Tiger'''||564|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Flash'''||565|| 1008, 1009, 1010, 1025, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1150, 1151, 1152, 1153&lt;br /&gt;
|-&lt;br /&gt;
|'''Tahoma'''||566|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Savanna'''||567|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1102, 1129, 1130, 1131, 1132, 1133, 1186, 1187, 1188, 1189&lt;br /&gt;
|-&lt;br /&gt;
|'''Bandito'''||568|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Freight Flat'''||569&lt;br /&gt;
|-&lt;br /&gt;
|'''Streak Carriage'''||570&lt;br /&gt;
|-&lt;br /&gt;
|'''Kart'''||571|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Mower'''||572|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Duneride'''||573|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Sweeper'''||574|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Broadway'''||575|| 1008, 1009, 1010, 1025, 1042, 1043, 1044, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1099, 1174, 1175, 1176, 1177&lt;br /&gt;
|-&lt;br /&gt;
|'''Tornado'''||576|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1134, 1135, 1136, 1137, 1190, 1191, 1192, 1193&lt;br /&gt;
|-&lt;br /&gt;
|'''AT-400'''||577|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''DFT-30'''||578|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Huntley'''||579|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Stafford'''||580|| 1001, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''BF-400'''||581&lt;br /&gt;
|-&lt;br /&gt;
|'''Newsvan'''||582|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Tug'''||583|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Trailer 3'''||584|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Emperor'''||585|| 1000, 1002, 1003, 1006, 1007, 1008, 1009, 1010, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Wayfarer'''||586&lt;br /&gt;
|-&lt;br /&gt;
|'''Euros'''||587|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Hotdog'''||588|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Club'''||589|| 1000, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1016, 1017, 1018, 1020, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Freight Carriage'''||590&lt;br /&gt;
|-&lt;br /&gt;
|'''Trailer 3'''||591|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Andromada'''||592|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Dodo'''||593|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''RC Cam'''||594|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Launch'''||595&lt;br /&gt;
|-&lt;br /&gt;
|'''Police Car (LSPD)'''||596|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Police Car (SFPD)'''||597|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Police Car (LVPD)'''||598|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Police Ranger'''||599|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Picador'''||600|| 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1018, 1020, 1022, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''S.W.A.T. Van'''||601|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Alpha'''||602|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Phoenix'''||603|| 1001, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1020, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145&lt;br /&gt;
|-&lt;br /&gt;
|'''Glendale'''||604|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Sadler'''||605|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Luggage Trailer A'''||606|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Luggage Trailer B'''||607|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Stair Trailer'''||608|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Boxville'''||609|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Farm Plow'''||610|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|-&lt;br /&gt;
|'''Utility Trailer'''||611|| 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Vehicle Functions==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Functions&amp;quot; class=&amp;quot;Server client&amp;quot;&amp;gt; {{Vehicle functions}} &amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Vehicles Upgrades (table form)==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Table (click to expand)&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  [1000] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_mar_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Pro&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1001] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_bab_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Win&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1002] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_bar_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Drag&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1003] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_mab_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alpha&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1004] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bnt_b_sc_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Vents&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Champ Scoop&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1005] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bnt_b_sc_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Vents&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Fury Scoop&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1006] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_b_sc_r&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Roof Scoop&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1007] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_b_ssk&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1008] = {&lt;br /&gt;
    cars = &amp;quot;Most cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;nto_b_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Nitro&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;5 times&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1009] = {&lt;br /&gt;
    cars = &amp;quot;Most cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;nto_b_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Nitro&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;2 times&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1010] = {&lt;br /&gt;
    cars = &amp;quot;Most cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;nto_b_tw&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Nitro&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;10 times&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1011] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bnt_b_sc_p_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Vents&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Race Scoop&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1012] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bnt_b_sc_p_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Vents&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Worx Scoop&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1013] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;lgt_b_rspt&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Lamps&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Round Fog&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1014] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_bar_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Champ&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1015] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_bbr_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Race&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1016] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_bbr_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Worx&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1017] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_b_ssk&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1018] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_b_ts&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Upswept&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1019] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_b_t&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Twin&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1020] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_b_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Large&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1021] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_b_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Medium&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1022] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_b_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Small&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1023] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_b_bbb_m&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Fury&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1024] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;lgt_b_sspt&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Lamps&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Square Fog&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1026] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_a_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1027] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_a_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1028] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_a_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1029] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_c_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1030] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_c_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1031] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_c_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1032] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_a_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien Roof Vent&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1033] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_c_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow Roof Vent&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1034] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_a_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1035] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_c_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow Roof Vent&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1036] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_a_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1037] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_c_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1038] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_a_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien Roof Vent&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1039] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_c_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1040] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_a_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1041] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_c_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1045] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_c_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1046] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_a_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1047] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_a_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1048] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_c_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1049] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_a_f_r&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1050] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_c_f_r&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1051] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_a_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1052] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_c_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;SideSkirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1053] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_c_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1054] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_a_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1055] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_a_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1056] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_a_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1057] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_c_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1058] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_a_st_r&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1059] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_c_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1060] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_c_st_r&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1061] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_c_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1062] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_a_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1063] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_c_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1064] = {&lt;br /&gt;
    cars = &amp;quot;Statum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_a_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1065] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_a_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1066] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_c_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1067] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_a_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1068] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_c_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1069] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_a_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1070] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_c_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1071] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_a_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1072] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_c_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1086] = {&lt;br /&gt;
    cars = &amp;quot;Most cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;stereo&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Stereo&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Stereo&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1087] = {&lt;br /&gt;
    cars = &amp;quot;Most cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;hydralics&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Hydraulics&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Hydraulics&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1088] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_a_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1089] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_c_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1090] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_a_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1091] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rf_c_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Roof&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1092] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;exh_a_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Exhaust&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1093] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_c_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1094] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_a_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Alien Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1095] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_c_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right X-Flow Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1102] = {&lt;br /&gt;
    cars = &amp;quot;Savanna&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_r_lr_sv&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left `Chrome Strip` Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1133] = {&lt;br /&gt;
    cars = &amp;quot;Savanna&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;wg_l_lr_sv&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Sideskirt&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right `Chrome Strip` Sideskirt&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1138] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_a_s_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1139] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_c_s_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1140] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_c_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1141] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_a_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1142] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender Cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bntr_b_ov&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Hood&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Oval Hoods&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1143] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender Cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bntl_b_ov&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Hood&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Oval Hoods&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1144] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender Cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bntr_b_sq&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Hood&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Left Square Hoods&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1145] = {&lt;br /&gt;
    cars = &amp;quot;Certain Transfender Cars&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;bntl_b_sq&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Hood&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Right Square Hoods&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1146] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_c_l_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1147] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_a_l_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1148] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_c_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1149] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_a_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1150] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_a_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1151] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_c_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1152] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_c_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1153] = {&lt;br /&gt;
    cars = &amp;quot;Flash&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_a_f&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1154] = {&lt;br /&gt;
    cars = &amp;quot;Stratum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_a_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1155] = {&lt;br /&gt;
    cars = &amp;quot;Stratum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_a_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1156] = {&lt;br /&gt;
    cars = &amp;quot;Stratum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_c_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1157] = {&lt;br /&gt;
    cars = &amp;quot;Stratum&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_c_st&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1158] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_c_j_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1159] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_a_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1160] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_a_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1161] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_c_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1162] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_a_j_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1163] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_c_u_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1164] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;spl_a_u_b&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Spoiler&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1165] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_c_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1166] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_a_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1167] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_c_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1168] = {&lt;br /&gt;
    cars = &amp;quot;Uranus&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;rbmp_a_u&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Rear Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1169] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_a_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1170] = {&lt;br /&gt;
    cars = &amp;quot;Sultan&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_c_s&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1171] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_a_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;Alien&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1172] = {&lt;br /&gt;
    cars = &amp;quot;Elegy&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_c_l&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  [1173] = {&lt;br /&gt;
    cars = &amp;quot;Jester&amp;quot;,&lt;br /&gt;
    modelName = &amp;quot;fbmp_c_j&amp;quot;,&lt;br /&gt;
    part = &amp;quot;Front Bumper&amp;quot;,&lt;br /&gt;
    partType = &amp;quot;X-Flow&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==All valid upgrades per vehicle (table form)==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Table (click to expand)&amp;quot; show=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
tunning_avalible = {&lt;br /&gt;
    [400] = { 1008, 1009, 1010, 1013, 1018, 1019, 1020, 1021, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [401] = { 1001, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1146, 1147, 1158, 1162, 1163 },&lt;br /&gt;
    [402] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [403] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [404] = { 1000, 1002, 1007, 1008, 1009, 1010, 1013, 1016, 1017, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [405] = { 1000, 1001, 1008, 1009, 1010, 1014, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [406] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [407] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [408] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [409] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [410] = { 1001, 1003, 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1021, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [411] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [412] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [413] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [414] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [415] = { 1001, 1003, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [416] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [417] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [418] = { 1002, 1006, 1008, 1009, 1010, 1016, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [419] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [420] = { 1001, 1003, 1004, 1005, 1008, 1009, 1010, 1019, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [421] = { 1000, 1008, 1009, 1010, 1014, 1016, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [422] = { 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [423] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [424] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [425] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [426] = { 1001, 1003, 1004, 1005, 1006, 1008, 1009, 1010, 1019, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [427] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [428] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [429] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [430] = { },&lt;br /&gt;
    [431] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [432] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [433] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [434] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [436] = { 1001, 1003, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1019, 1020, 1021, 1022, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [437] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [438] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [439] = { 1001, 1003, 1007, 1008, 1009, 1010, 1013, 1017, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [440] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [441] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [442] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [443] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [444] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [445] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [446] = { },&lt;br /&gt;
    [447] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [448] = { },&lt;br /&gt;
    [449] = { },&lt;br /&gt;
    [451] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [452] = { },&lt;br /&gt;
    [453] = { },&lt;br /&gt;
    [454] = { },&lt;br /&gt;
    [455] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [456] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [457] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [458] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [459] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [460] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [461] = { },&lt;br /&gt;
    [462] = { },&lt;br /&gt;
    [463] = { },&lt;br /&gt;
    [464] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [465] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [466] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [467] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [468] = { 1086 },&lt;br /&gt;
    [469] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [470] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [471] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [472] = { },&lt;br /&gt;
    [473] = { },&lt;br /&gt;
    [474] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [475] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [476] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [478] = { 1004, 1005, 1008, 1009, 1010, 1012, 1013, 1020, 1021, 1022, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [479] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [480] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [481] = { },&lt;br /&gt;
    [482] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [483] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [484] = { },&lt;br /&gt;
    [485] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [486] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [487] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [488] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [489] = { 1000, 1002, 1004, 1005, 1006, 1008, 1009, 1010, 1013, 1016, 1018, 1019, 1020, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [490] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [491] = { 1003, 1007, 1008, 1009, 1010, 1014, 1017, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [492] = { 1000, 1004, 1005, 1006, 1008, 1009, 1010, 1016, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [493] = { },&lt;br /&gt;
    [494] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [495] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [496] = { 1001, 1002, 1003, 1006, 1007, 1008, 1009, 1010, 1011, 1017, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143 },&lt;br /&gt;
    [497] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [498] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [499] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [500] = { 1008, 1009, 1010, 1013, 1019, 1020, 1021, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [501] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [502] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [503] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [504] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [505] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [506] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [507] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [508] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [509] = { },&lt;br /&gt;
    [510] = { },&lt;br /&gt;
    [511] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [512] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [513] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [514] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [515] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [516] = { 1000, 1002, 1004, 1007, 1008, 1009, 1010, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [517] = { 1002, 1003, 1007, 1008, 1009, 1010, 1016, 1017, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [518] = { 1001, 1003, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1018, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [519] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [520] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [521] = { },&lt;br /&gt;
    [522] = { },&lt;br /&gt;
    [523] = { },&lt;br /&gt;
    [524] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [525] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [526] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [527] = { 1001, 1007, 1008, 1009, 1010, 1014, 1015, 1017, 1018, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [528] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [529] = { 1001, 1003, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1017, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [530] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [531] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [532] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [533] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [534] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1100, 1101, 1106, 1122, 1123, 1124, 1125, 1126, 1127, 1178, 1179, 1180, 1185 },&lt;br /&gt;
    [535] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1109, 1110, 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121 },&lt;br /&gt;
    [536] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1103, 1104, 1105, 1107, 1108, 1128, 1181, 1182, 1183, 1184 },&lt;br /&gt;
    [537] = { },&lt;br /&gt;
    [538] = { },&lt;br /&gt;
    [539] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [540] = { 1001, 1004, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1020, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [541] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [542] = { 1008, 1009, 1010, 1014, 1015, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1144, 1145 },&lt;br /&gt;
    [543] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [544] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [545] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [546] = { 1001, 1002, 1004, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [547] = { 1000, 1003, 1008, 1009, 1010, 1016, 1018, 1019, 1020, 1021, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143 },&lt;br /&gt;
    [548] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [549] = { 1001, 1003, 1007, 1008, 1009, 1010, 1011, 1012, 1017, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [550] = { 1001, 1003, 1004, 1005, 1006, 1008, 1009, 1010, 1018, 1019, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [551] = { 1002, 1003, 1005, 1006, 1008, 1009, 1010, 1016, 1018, 1019, 1020, 1021, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [552] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [553] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [554] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [555] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [556] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [557] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [558] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1163, 1164, 1165, 1166, 1167, 1168 },&lt;br /&gt;
    [559] = { 1008, 1009, 1010, 1025, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1158, 1159, 1160, 1161, 1162, 1173 },&lt;br /&gt;
    [560] = { 1008, 1009, 1010, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1138, 1139, 1140, 1141, 1169, 1170 },&lt;br /&gt;
    [561] = { 1008, 1009, 1010, 1025, 1026, 1027, 1030, 1031, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1154, 1155, 1156, 1157 },&lt;br /&gt;
    [562] = { 1008, 1009, 1010, 1025, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1146, 1147, 1148, 1149, 1171, 1172 },&lt;br /&gt;
    [563] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [564] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [565] = { 1008, 1009, 1010, 1025, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1150, 1151, 1152, 1153 },&lt;br /&gt;
    [566] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [567] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1102, 1129, 1130, 1131, 1132, 1133, 1186, 1187, 1188, 1189 },&lt;br /&gt;
    [568] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [569] = { },&lt;br /&gt;
    [570] = { },&lt;br /&gt;
    [571] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [572] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [573] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [574] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [575] = { 1008, 1009, 1010, 1025, 1042, 1043, 1044, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1099, 1174, 1175, 1176, 1177 },&lt;br /&gt;
    [576] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1134, 1135, 1136, 1137, 1190, 1191, 1192, 1193 },&lt;br /&gt;
    [579] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [580] = { 1001, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1020, 1023, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [581] = { },&lt;br /&gt;
    [582] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [583] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [585] = { 1000, 1002, 1003, 1006, 1007, 1008, 1009, 1010, 1013, 1014, 1015, 1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [587] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [586] = { },&lt;br /&gt;
    [588] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [589] = { 1000, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1016, 1017, 1018, 1020, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1144, 1145 },&lt;br /&gt;
    [590] = { },&lt;br /&gt;
    [591] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [592] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [593] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [594] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [595] = { },&lt;br /&gt;
    [596] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [597] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [598] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [599] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [600] = { 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1013, 1017, 1018, 1020, 1022, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [601] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [602] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [603] = { 1001, 1006, 1007, 1008, 1009, 1010, 1017, 1018, 1019, 1020, 1023, 1024, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098, 1142, 1143, 1144, 1145 },&lt;br /&gt;
    [604] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [605] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [606] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [607] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [608] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [609] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [610] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 },&lt;br /&gt;
    [611] = { 1008, 1009, 1010, 1025, 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1096, 1097, 1098 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
[[id|ID Lists]]&lt;br /&gt;
&lt;br /&gt;
[[hu:Vehicle Upgrades]]&lt;br /&gt;
[[pl:Vehicle_Upgrades]]&lt;br /&gt;
[[it:Miglioramenti Veicoli]]&lt;br /&gt;
&lt;br /&gt;
[[Category:ID Lists]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=CEF_Tutorial&amp;diff=71138</id>
		<title>CEF Tutorial</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=CEF_Tutorial&amp;diff=71138"/>
		<updated>2021-05-31T13:48:01Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page gives you a brief introduction to CEF.&lt;br /&gt;
&lt;br /&gt;
=What is CEF?=&lt;br /&gt;
CEF stands for '''C'''hromium '''E'''mbedded '''F'''ramework and is a framework for embedding Chromium-based browsers in other applications - in our case MTA. CEF is based on Google's Chromium project so it is also a fast, secure and stable web engine.&lt;br /&gt;
&lt;br /&gt;
You can find more information about CEF on CEF's GoogleCode project page: https://bitbucket.org/chromiumembedded/cef&lt;br /&gt;
&lt;br /&gt;
=The basics=&lt;br /&gt;
Creating a new browser is really simple. Let's open YouTube for example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- Create a new remote browser (size is 800*600px) with transparency enabled&lt;br /&gt;
local browser = createBrowser(800, 600, true, true)&lt;br /&gt;
&lt;br /&gt;
-- &amp;quot;Wait&amp;quot; for the browser (this is necessary because CEF runs in a secondary thread and hence requires the 'asynchronous' event mechanism)&lt;br /&gt;
addEventHandler(&amp;quot;onClientBrowserCreated&amp;quot;, browser,&lt;br /&gt;
    function()&lt;br /&gt;
        -- We're ready to load the URL now (the source of this event is the browser that has been created)&lt;br /&gt;
        loadBrowserURL(source, &amp;quot;https://youtube.com/&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This example does not require any domain requests as YouTube is whitelisted by default. More about domain requests below.&lt;br /&gt;
&lt;br /&gt;
=Domain request system=&lt;br /&gt;
In order to prevent people from abusing the possibilities CEF offers, we decided to introduce a request system.&lt;br /&gt;
This means the domain you want to load has to meet at least one of the following requirements:&lt;br /&gt;
*it is whitelisted globally by the MTA team (you can create a post in [this topic] to suggest a new domain to be whitelisted) - '''**TODO: Add forum URL here**'''&lt;br /&gt;
*the domain was requested via requestBrowserDomains/Browser.requestDomains and accepted by the player '''before'''&lt;br /&gt;
*the domain is on the user's whitelist (MTA settings =&amp;gt; Tab: Browser =&amp;gt; Whitelist)&lt;br /&gt;
&lt;br /&gt;
Apart from these options, a domain might be blacklisted due to malicious content. Such domains cannot be requested.&lt;br /&gt;
&lt;br /&gt;
=Local vs remote mode=&lt;br /&gt;
There are two modes CEF can run in:&lt;br /&gt;
&lt;br /&gt;
Characteristics of local mode:&lt;br /&gt;
*you '''can''' execute Javascript code without any restriction (See: [[executeBrowserJavascript]])&lt;br /&gt;
*you '''can''' only load websites stored in the resource folder&lt;br /&gt;
*you '''cannot''' load remote content&lt;br /&gt;
&lt;br /&gt;
Characteristics of remote mode:&lt;br /&gt;
*you '''cannot''' execute Javascript code&lt;br /&gt;
*you '''can''' only load remote content&lt;br /&gt;
*keep in mind that either loading remote websites or Javascript on remote websites can be disabled in the MTA settings&lt;br /&gt;
&lt;br /&gt;
Changing the mode after the browser was created is not possible due to technical reasons.&lt;br /&gt;
&lt;br /&gt;
=Resource management=&lt;br /&gt;
==How to load local HTML files==&lt;br /&gt;
Loading local HTML files works similar to loading images.&lt;br /&gt;
&lt;br /&gt;
Add your HTML files to your meta.xml through the file tag:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;file src=&amp;quot;html/myAwesomeUI.html&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==How to load local resources in local HTML files==&lt;br /&gt;
Imagine you want to load an image or play a video from your MTA resource. This is possible via a custom URI scheme named '''''&amp;quot;http://mta/&amp;quot;'''''&lt;br /&gt;
&lt;br /&gt;
===Example===&lt;br /&gt;
This examples shows how to play a video. Note that you have to enable OOP.&lt;br /&gt;
====Lua====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
-- Create a browser (local mode is also required to access local data)&lt;br /&gt;
local webView = Browser(640, 480, true, true)&lt;br /&gt;
&lt;br /&gt;
addEventHandler(&amp;quot;onClientBrowserCreated&amp;quot;, webView,&lt;br /&gt;
     function()&lt;br /&gt;
    &lt;br /&gt;
          -- Load HTML UI&lt;br /&gt;
          webView:loadURL(&amp;quot;http://mta/local/html/myVideo.html&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
     end&lt;br /&gt;
)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====meta.xml====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;file src=&amp;quot;html/myVideo.html&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;file src=&amp;quot;media/myVideo.webm&amp;quot;/&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
====HTML====&lt;br /&gt;
This is the most interesting part:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE HTML&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
    &amp;lt;video width=&amp;quot;640&amp;quot; height=&amp;quot;480&amp;quot; controls&amp;gt;&lt;br /&gt;
         &amp;lt;source src=&amp;quot;http://mta/local/myVideo.webm&amp;quot; type=&amp;quot;video/webm&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/video&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Lua &amp;lt;==&amp;gt; Javascript communication=&lt;br /&gt;
First of all, communication between Lua and Javascript is only available in local mode due to security reasons.&lt;br /&gt;
&lt;br /&gt;
==Lua to Javascript==&lt;br /&gt;
Lua to javascript is pretty easy as you can execute Javascript code from Lua using [[executeBrowserJavascript]].&lt;br /&gt;
&lt;br /&gt;
So, a bit Lua code around it and you have got the first direction:&lt;br /&gt;
* https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/src/WebWindow.lua#L180-189&lt;br /&gt;
* https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/src/mtaevents.js#L9-L15&lt;br /&gt;
&lt;br /&gt;
==Javascript to Lua==&lt;br /&gt;
You are able to trigger a client event via the Javascript method ''triggerEvent'' which is part of the static class/namespace ''mta''.&lt;br /&gt;
The syntax is as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
mta.triggerEvent(string event, var parameter1, var parameter2, var parameter3, ...)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The source of this event is always the browser element that triggered the event.&lt;br /&gt;
&lt;br /&gt;
An example is available here:&lt;br /&gt;
* https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/examples/html/ui2.html#L66&lt;br /&gt;
* https://github.com/Jusonex/mtasa_cef_tools/blob/master/webui/examples/Main.lua#L35-L40&lt;br /&gt;
&lt;br /&gt;
=Debugging=&lt;br /&gt;
The ''web development mode'' can be enabled as follows (type it in the client's F8 console):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;start runcode&lt;br /&gt;
crun setDevelopmentMode(true, true)&lt;br /&gt;
debugscript 3&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Now, you should be able to see web errors and blocked domains/URLs in the debug window at the bottom.&lt;br /&gt;
&lt;br /&gt;
=Things you should keep in mind while working with CEF=&lt;br /&gt;
You should always keep in mind that some modern browser features are not available on some computers.&lt;br /&gt;
This is for example true for '''WebGL'''.&lt;br /&gt;
&lt;br /&gt;
Another problematic feature is '''Adobe Flash'''. Adobe Flash is enabled by default, but you should avoid using it due to the fact that plugins can be disabled in the settings on the one hand (Java is disabled completely by the way) and Flash is very restrictive on the other hand. Restrictive means it runs in a separate process uses a very old interface and offers therefore just a few ways to control it.&lt;br /&gt;
As a consequence, you cannot control the volume of flash objects. Fortunately, HTML5 is an even better replacement and provides very good audio and video interface (http://www.w3schools.com/tags/ref_av_dom.asp) which even supports 3D sound (@all bored people among us: Feel free to write a 3D sound 'wrapper' that maps the GTA onto HTML5 coordinates :P).&lt;br /&gt;
&lt;br /&gt;
=Advanced usage=&lt;br /&gt;
Since our CEF implementation does not do z-ordering by default, you have to provide your own z-ordering mechanism.&lt;br /&gt;
You can find a basic implementation of such a mechanism here: https://github.com/Jusonex/mtasa_cef_tools&lt;br /&gt;
There are also a few utility functions that allow you to integrate these classes easily into your own object-oriented UI system.&lt;br /&gt;
I'll provide some code to use CEF along with CEGUI soon too.&lt;br /&gt;
&lt;br /&gt;
=Performance=&lt;br /&gt;
Creating lots of browsers does not influence MTA directly (except the fact MTA has to copy the texture data in the main/GTA thread due to technical restrictions), because one part of CEF runs in another process and the other part in a secondary thread.&lt;br /&gt;
So if you do not want to show the browser, it is definitely the best to destroy the browser. If you cannot destroy the browser (imagine you have to save the website's state for some reason), you can save a lot of resources by disabling rendering via [[setBrowserRenderingPaused]]. This will stop CEF from rendering new frames/processing input and MTA from copying the texture data.&lt;br /&gt;
&lt;br /&gt;
=Troubleshooting=&lt;br /&gt;
===google.com doesn't work (even though I requested google.com)===&lt;br /&gt;
Google redirects to a country-specific website by default. If you want to prevent Google from doing this, load the following URL: https://www.google.com/ncr&lt;br /&gt;
&lt;br /&gt;
=3-rd party=&lt;br /&gt;
&lt;br /&gt;
==Typescript==&lt;br /&gt;
Typescript declaration for mta functions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ts&amp;quot;&amp;gt;&lt;br /&gt;
declare var mta: {&lt;br /&gt;
    triggerEvent(event: string): void;&lt;br /&gt;
    triggerEvent(event: string, ...any): void;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==React==&lt;br /&gt;
Example how to call react function from mta:&lt;br /&gt;
1. Create a hook:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ts&amp;quot;&amp;gt;&lt;br /&gt;
const useMta = () =&amp;gt; {&lt;br /&gt;
  const dispatch = yourDispatcherHere();&lt;br /&gt;
  const w = window as any;&lt;br /&gt;
  w.MtaPrefixSomeName = () =&amp;gt; dispatch(dispatchFunction());&lt;br /&gt;
}&lt;br /&gt;
export default useMta;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
2. Add this hook to main App component.&lt;br /&gt;
&lt;br /&gt;
3. Call from lua:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function callReactFunction(name, arg)&lt;br /&gt;
    local name = string.format(name, &amp;quot;[^a-zA-Z0-9]&amp;quot;, &amp;quot;&amp;quot;);&lt;br /&gt;
    local code;&lt;br /&gt;
    if(arg~= nil)then&lt;br /&gt;
        code = string.format(&amp;quot;MtaPrefix%s(%q)&amp;quot;,name, arg)&lt;br /&gt;
    else&lt;br /&gt;
        code = string.format(&amp;quot;MtaPrefix%s()&amp;quot;,name)&lt;br /&gt;
    end&lt;br /&gt;
    return executeBrowserJavascript(theBrowser, code)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Use of prefix let you call only mta specific functions with bare minimum of validation required.&lt;br /&gt;
option `%q` puts quotes around a string argument's value. Read more at https://www.gammon.com.au/scripts/doc.php?lua=string.format&lt;br /&gt;
&lt;br /&gt;
=Scripting functions=&lt;br /&gt;
{{CEF_functions}}&lt;br /&gt;
=Scripting events=&lt;br /&gt;
{{CEF_events}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
&lt;br /&gt;
[[pt-br:Tutorial_CEF]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetColPolygonHeight&amp;diff=69563</id>
		<title>SetColPolygonHeight</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetColPolygonHeight&amp;diff=69563"/>
		<updated>2021-03-02T15:05:54Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Server client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
{{New feature/item|3.0160|1.5.8|20807|This function is used to change the height of an existing [[createColPolygon|colshape polygon]].&lt;br /&gt;
By default, a colshape polygon is infinitely tall.}}&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setColPolygonHeight( colshape shape, float floor, float ceil )  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{OOP||[[colshape]]:setHeight|}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''shape:''' The [[colshape]] polygon&lt;br /&gt;
*'''floor:''' The polygon floor (lowest Z coordinate). Parse ''false'' to reset this value to infinitely tall in negative z coord, equivalent of &amp;quot;math.min&amp;quot;.&lt;br /&gt;
*'''ceil:''' The polygon ceiling (highest Z coordinate). Parse ''false'' to reset this value to infinitely tall in positive z coord, equivalent of &amp;quot;math.max&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the polygon was changed, ''false'' if invalid arguments were passed.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example sets every polygon colshape's max heigh to 50 units once resource starts.&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server side script&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function setPolygonsHeight()&lt;br /&gt;
    for i, v in ipairs(getElementsByType(&amp;quot;colshape&amp;quot;)) do&lt;br /&gt;
        if (getColShapeType(v) == 4) then -- if it's a polygon colshape do it otherwise don't&lt;br /&gt;
            setColPolygonHeight(v, false, 50)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, resourceRoot, setPolygonsHeight)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
{{Requirements|1.5.8-9.20807|1.5.8-9.20807|}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Collision_shape_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=SetColPolygonHeight&amp;diff=68264</id>
		<title>SetColPolygonHeight</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=SetColPolygonHeight&amp;diff=68264"/>
		<updated>2021-01-17T08:40:30Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;{{Server client function}} __NOTOC__ {{New feature/item|3.0158|1.5.7|20397|This function is used to change height of an existing colshape polygon.}}  ==Sy...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Server client function}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
{{New feature/item|3.0158|1.5.7|20397|This function is used to change height of an existing [[createColPolygon|colshape polygon]].}}&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool setColPolygonHeight( colshape shape, float fFloor, float fCeil)  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
{{OOP||[[colshape]]:setHeight|}}&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''shape:''' The [[colshape]] polygon&lt;br /&gt;
*'''fFloor:''' The polygon floor&lt;br /&gt;
*'''fCeil:''' The polygon ceil&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns ''true'' if the polygon was changed, ''false'' if invalid arguments were passed.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
TODO&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
{{Requirements|1.5.7-9.20397|1.5.7-9.20397|}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Collision_shape_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Scripting_Tips&amp;diff=68164</id>
		<title>Scripting Tips</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Scripting_Tips&amp;diff=68164"/>
		<updated>2021-01-05T20:56:09Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Speed comparison between structural and OOP scripting */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a variety of things that knowing, make life easier for MTA scripters.&lt;br /&gt;
&lt;br /&gt;
== General Lua ==&lt;br /&gt;
* The ''infinite loop / too long execution error'' which aborts execution can be disabled with ''debug.sethook(nil)''&lt;br /&gt;
* Be careful when looping a table where you intend to delete multiple rows, if 2 of them are in a row the 2nd one will get skipped! You must loop the table backwards (reverse ipairs). For example: ''for i = #table, 1, -1 do''&lt;br /&gt;
* Rather than having if checks inside if checks inside if checks, consider using ''return'' for example ''if (not ready) then return false end''&lt;br /&gt;
* Keep event, variable &amp;amp; function names short but understandable - longer names will make the file larger in size. In client files, this will increase download time.&lt;br /&gt;
* Remember that 'false' boolean has a value - If you want to delete a variable or element/account data, use 'nil' instead - this will reduce memory and disk usage (minuscule optimization, only notable on larger servers)&lt;br /&gt;
&lt;br /&gt;
== MTA Scripting ==&lt;br /&gt;
* Remember that 99% of the time it's a bug in your script, not an MTA bug! Don't report something to GitHub Issues until you're absolutely certain the bug can be reproduced with a small piece of script.&lt;br /&gt;
* As MTA already has so many functions and events virtually everything you want to do is already possible, as long as you're willing to do the work! You'll find better solutions to problems as there are many ways to achieve the same thing as long as you know all the functions and events.&lt;br /&gt;
* If a script is getting too complicated, try putting back-end stuff in another file so the main script calls the functions in the 2nd one. For example rather than having meaningless things like ''vehicleTable[vehicle][7]'' in the main file, put that in a function in the 2nd file and have the main file call a meaningfully named function so rather than seeing a useless ''7'' you'd see something like ''getFuel'' and although this might take longer to set-up you'll save time in the long run as you'll spend less time being confused when you come back to it in a weeks time to debug a problem.&lt;br /&gt;
* Your client side scripts can cause desync if you're not careful, try to keep the psychical world equal with every player. For example if your script creates a client side object make sure your script will create it for everyone nearby, else people will be wondering why a player appears to be constantly floating and falling.&lt;br /&gt;
* Instead of using ''onClientResourceStart'' or ''onResourceStart'' events attached to ''resourceRoot'' like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function warnPeopleThatThisResourceStarted()&lt;br /&gt;
    outputChatBox(&amp;quot;The resource &amp;quot; .. getResourceName(resource) .. &amp;quot; has just started!&amp;quot;, 0, 255, 0)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, warnPeopleThatThisResourceStarted)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You can also use this outside of any function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;outputChatBox(&amp;quot;The resource &amp;quot; .. getResourceName(resource) .. &amp;quot; has just started!&amp;quot;, 0, 255, 0)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And the result will be the same, because Lua executes every instruction in every script file of a resource when it starts.&lt;br /&gt;
* string.dump produces unsigned compiled Lua code which is not allowed for security reasons. The only way to transport code now is by using the source code. e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;exampleFunction = [===[&lt;br /&gt;
    return param&lt;br /&gt;
]===]&lt;br /&gt;
&lt;br /&gt;
local loadedFunction = loadstring(exampleFunction)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MTA Scripting - Element IDs Being Reused ==&lt;br /&gt;
* If your script is covered in [[isTimer]] and [[isElement]] checks to hide debug warnings from deleted elements not being dereferenced (making the variable nil) you will regret it when that element ID or timer pointer has to be re-used by MTA in a weeks time and your script starts acting strangely and you won't have a clue why. Dereference destroyed elements and disconnected players!&lt;br /&gt;
* Why would MTA reuse it in a weeks time? Everything has a userdata value whether it's a function or an element, there is a limited amount of these available meaning that eventually the server will be forced to use the same userdata value twice, as long as whatever that userdata value was for is no longer valid. This could happen within hours, weeks or even never depending on how many elements are being created and destroyed by your scripts.&lt;br /&gt;
* For example if you have a race server that has 100 objects in every map and the map was changing every 5 minutes your server would go through at least 1200 an hour, 28,800 a day, 201,600 a week in userdata values, it can't keep going up and up though eventually it will have to reuse the same userdata values and as long as you're dereferencing in your scripts, it won't be a problem.&lt;br /&gt;
&lt;br /&gt;
The is an example of a script which fails to dereference, because when the player quits their userdata value remains in the table, but what if in a weeks time another player joins and they get assigned the same userdata value?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local admins = {}&lt;br /&gt;
local secretPasswordOnlyAdminsShouldKnow = &amp;quot;12345678&amp;quot;&lt;br /&gt;
&lt;br /&gt;
function adminLogin()&lt;br /&gt;
    if (hasObjectPermissionTo(source, &amp;quot;command.ban&amp;quot;, false)) then&lt;br /&gt;
        admins[source] = true&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerLogin&amp;quot;, root, adminLogin)&lt;br /&gt;
&lt;br /&gt;
function cmdGetSecretPassword(plr)&lt;br /&gt;
    if (not admins[plr]) then&lt;br /&gt;
        return false&lt;br /&gt;
    end&lt;br /&gt;
    outputChatBox(&amp;quot;The secret password is &amp;quot;..secretPasswordOnlyAdminsShouldKnow, plr)&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;getsecretpass&amp;quot;, cmdGetSecretPassword)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some random player who joins in a weeks time gets the same userdata value as an admin, that player can now use &amp;quot;getsecretpass&amp;quot;. Solution? De-reference on destruction!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function onQuit()&lt;br /&gt;
    admins[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onQuit)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server Performance ==&lt;br /&gt;
* Server lagging? Check [[Debugging#Debugging_Performance_Issues|this page of debugging performance issues]]&lt;br /&gt;
* Using resourceRoot in event handlers for events from clients is much more efficient than using root.&lt;br /&gt;
* Try to be efficient, but if what you're doing is too time consuming or complex, is it really efficient?&lt;br /&gt;
* It's much more efficient to [[SetElementHealth]] and [[setElementRotation]] on a player client side, consider a client event all your server scripts can call to set a players health.&lt;br /&gt;
* Unless you have hundreds of players, don't worry about making little optimizations, check ''performancebrowser'' or ''ipb'' (ingame performancebrowser) and make sure no resource is using significantly more than the others.&lt;br /&gt;
&lt;br /&gt;
== Client Performance ==&lt;br /&gt;
* The biggest cause of client script CPU usage is anything done in onClient/Pre/Hud/Render because it is called so often. For example if you have a script which calls dxDrawLine3D 20 times, 60 times a second, if those lines are only in 1 part of the map, consider adding a [[getDistanceBetweenPoints3D]] check between the local player and the general area that those lines are in and if they're no where near the player, don't draw the lines.&lt;br /&gt;
* Another thing that gets called a lot and could therefore be quite consuming if not careful are events like [[onClientPlayerWeaponFire]] and [[onClientPlayerDamage]] so any scripts that use these should only be bound to the necessary elements (such as localPlayer instead of root) and run the simplest if statements for example if you wanted to handle a certain weapon being fired in a certain dimension it's better to check weapon first as that's a simple weaponID == x rather than getElementDimension(source) == y.&lt;br /&gt;
* Start checking variables since least aggravating. Example, first do simple checks: interior, dimension, distance, then check elementDatas, exports etc.&lt;br /&gt;
&lt;br /&gt;
== Speed comparison between local and global variables ==&lt;br /&gt;
&lt;br /&gt;
=== Slower ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
a = 1&lt;br /&gt;
for i=1,10000000 do&lt;br /&gt;
   a = 1&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;global&amp;quot;, stop - start ) -- more than 500ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
local b = 1&lt;br /&gt;
for i=1,10000000 do&lt;br /&gt;
   b = 1&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;local&amp;quot;, stop - start ) -- less than 200ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Speed comparison between structural and OOP scripting ==&lt;br /&gt;
=== Slower ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
a = 1&lt;br /&gt;
for i=1,1000000 do&lt;br /&gt;
   a = localPlayer.position&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;variable&amp;quot;, stop - start ) -- more than 1500ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
b = nil&lt;br /&gt;
for i=1,1000000 do&lt;br /&gt;
   b = getElementPosition(localPlayer)&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;structural&amp;quot;, stop - start ) -- less than 200ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Scripting_Tips&amp;diff=68163</id>
		<title>Scripting Tips</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Scripting_Tips&amp;diff=68163"/>
		<updated>2021-01-05T20:55:58Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: fix typo, then -&amp;gt; than&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page contains a variety of things that knowing, make life easier for MTA scripters.&lt;br /&gt;
&lt;br /&gt;
== General Lua ==&lt;br /&gt;
* The ''infinite loop / too long execution error'' which aborts execution can be disabled with ''debug.sethook(nil)''&lt;br /&gt;
* Be careful when looping a table where you intend to delete multiple rows, if 2 of them are in a row the 2nd one will get skipped! You must loop the table backwards (reverse ipairs). For example: ''for i = #table, 1, -1 do''&lt;br /&gt;
* Rather than having if checks inside if checks inside if checks, consider using ''return'' for example ''if (not ready) then return false end''&lt;br /&gt;
* Keep event, variable &amp;amp; function names short but understandable - longer names will make the file larger in size. In client files, this will increase download time.&lt;br /&gt;
* Remember that 'false' boolean has a value - If you want to delete a variable or element/account data, use 'nil' instead - this will reduce memory and disk usage (minuscule optimization, only notable on larger servers)&lt;br /&gt;
&lt;br /&gt;
== MTA Scripting ==&lt;br /&gt;
* Remember that 99% of the time it's a bug in your script, not an MTA bug! Don't report something to GitHub Issues until you're absolutely certain the bug can be reproduced with a small piece of script.&lt;br /&gt;
* As MTA already has so many functions and events virtually everything you want to do is already possible, as long as you're willing to do the work! You'll find better solutions to problems as there are many ways to achieve the same thing as long as you know all the functions and events.&lt;br /&gt;
* If a script is getting too complicated, try putting back-end stuff in another file so the main script calls the functions in the 2nd one. For example rather than having meaningless things like ''vehicleTable[vehicle][7]'' in the main file, put that in a function in the 2nd file and have the main file call a meaningfully named function so rather than seeing a useless ''7'' you'd see something like ''getFuel'' and although this might take longer to set-up you'll save time in the long run as you'll spend less time being confused when you come back to it in a weeks time to debug a problem.&lt;br /&gt;
* Your client side scripts can cause desync if you're not careful, try to keep the psychical world equal with every player. For example if your script creates a client side object make sure your script will create it for everyone nearby, else people will be wondering why a player appears to be constantly floating and falling.&lt;br /&gt;
* Instead of using ''onClientResourceStart'' or ''onResourceStart'' events attached to ''resourceRoot'' like this:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;function warnPeopleThatThisResourceStarted()&lt;br /&gt;
    outputChatBox(&amp;quot;The resource &amp;quot; .. getResourceName(resource) .. &amp;quot; has just started!&amp;quot;, 0, 255, 0)&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, resourceRoot, warnPeopleThatThisResourceStarted)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
You can also use this outside of any function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;outputChatBox(&amp;quot;The resource &amp;quot; .. getResourceName(resource) .. &amp;quot; has just started!&amp;quot;, 0, 255, 0)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
And the result will be the same, because Lua executes every instruction in every script file of a resource when it starts.&lt;br /&gt;
* string.dump produces unsigned compiled Lua code which is not allowed for security reasons. The only way to transport code now is by using the source code. e.g.:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;exampleFunction = [===[&lt;br /&gt;
    return param&lt;br /&gt;
]===]&lt;br /&gt;
&lt;br /&gt;
local loadedFunction = loadstring(exampleFunction)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== MTA Scripting - Element IDs Being Reused ==&lt;br /&gt;
* If your script is covered in [[isTimer]] and [[isElement]] checks to hide debug warnings from deleted elements not being dereferenced (making the variable nil) you will regret it when that element ID or timer pointer has to be re-used by MTA in a weeks time and your script starts acting strangely and you won't have a clue why. Dereference destroyed elements and disconnected players!&lt;br /&gt;
* Why would MTA reuse it in a weeks time? Everything has a userdata value whether it's a function or an element, there is a limited amount of these available meaning that eventually the server will be forced to use the same userdata value twice, as long as whatever that userdata value was for is no longer valid. This could happen within hours, weeks or even never depending on how many elements are being created and destroyed by your scripts.&lt;br /&gt;
* For example if you have a race server that has 100 objects in every map and the map was changing every 5 minutes your server would go through at least 1200 an hour, 28,800 a day, 201,600 a week in userdata values, it can't keep going up and up though eventually it will have to reuse the same userdata values and as long as you're dereferencing in your scripts, it won't be a problem.&lt;br /&gt;
&lt;br /&gt;
The is an example of a script which fails to dereference, because when the player quits their userdata value remains in the table, but what if in a weeks time another player joins and they get assigned the same userdata value?&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
local admins = {}&lt;br /&gt;
local secretPasswordOnlyAdminsShouldKnow = &amp;quot;12345678&amp;quot;&lt;br /&gt;
&lt;br /&gt;
function adminLogin()&lt;br /&gt;
    if (hasObjectPermissionTo(source, &amp;quot;command.ban&amp;quot;, false)) then&lt;br /&gt;
        admins[source] = true&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerLogin&amp;quot;, root, adminLogin)&lt;br /&gt;
&lt;br /&gt;
function cmdGetSecretPassword(plr)&lt;br /&gt;
    if (not admins[plr]) then&lt;br /&gt;
        return false&lt;br /&gt;
    end&lt;br /&gt;
    outputChatBox(&amp;quot;The secret password is &amp;quot;..secretPasswordOnlyAdminsShouldKnow, plr)&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;getsecretpass&amp;quot;, cmdGetSecretPassword)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Some random player who joins in a weeks time gets the same userdata value as an admin, that player can now use &amp;quot;getsecretpass&amp;quot;. Solution? De-reference on destruction!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function onQuit()&lt;br /&gt;
    admins[source] = nil&lt;br /&gt;
end&lt;br /&gt;
addEventHandler(&amp;quot;onPlayerQuit&amp;quot;, root, onQuit)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Server Performance ==&lt;br /&gt;
* Server lagging? Check [[Debugging#Debugging_Performance_Issues|this page of debugging performance issues]]&lt;br /&gt;
* Using resourceRoot in event handlers for events from clients is much more efficient than using root.&lt;br /&gt;
* Try to be efficient, but if what you're doing is too time consuming or complex, is it really efficient?&lt;br /&gt;
* It's much more efficient to [[SetElementHealth]] and [[setElementRotation]] on a player client side, consider a client event all your server scripts can call to set a players health.&lt;br /&gt;
* Unless you have hundreds of players, don't worry about making little optimizations, check ''performancebrowser'' or ''ipb'' (ingame performancebrowser) and make sure no resource is using significantly more than the others.&lt;br /&gt;
&lt;br /&gt;
== Client Performance ==&lt;br /&gt;
* The biggest cause of client script CPU usage is anything done in onClient/Pre/Hud/Render because it is called so often. For example if you have a script which calls dxDrawLine3D 20 times, 60 times a second, if those lines are only in 1 part of the map, consider adding a [[getDistanceBetweenPoints3D]] check between the local player and the general area that those lines are in and if they're no where near the player, don't draw the lines.&lt;br /&gt;
* Another thing that gets called a lot and could therefore be quite consuming if not careful are events like [[onClientPlayerWeaponFire]] and [[onClientPlayerDamage]] so any scripts that use these should only be bound to the necessary elements (such as localPlayer instead of root) and run the simplest if statements for example if you wanted to handle a certain weapon being fired in a certain dimension it's better to check weapon first as that's a simple weaponID == x rather than getElementDimension(source) == y.&lt;br /&gt;
* Start checking variables since least aggravating. Example, first do simple checks: interior, dimension, distance, then check elementDatas, exports etc.&lt;br /&gt;
&lt;br /&gt;
== Speed comparison between local and global variables ==&lt;br /&gt;
&lt;br /&gt;
=== Slower ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
a = 1&lt;br /&gt;
for i=1,10000000 do&lt;br /&gt;
   a = 1&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;global&amp;quot;, stop - start ) -- more than 500ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
local b = 1&lt;br /&gt;
for i=1,10000000 do&lt;br /&gt;
   b = 1&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;local&amp;quot;, stop - start ) -- less than 200ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Speed comparison between structural and OOP scripting ==&lt;br /&gt;
=== Slower ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
a = 1&lt;br /&gt;
for i=1,1000000 do&lt;br /&gt;
   a = localPlayer.position&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;variable&amp;quot;, stop - start ) -- more then 1500ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Faster ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
start = getTickCount()&lt;br /&gt;
b = nil&lt;br /&gt;
for i=1,1000000 do&lt;br /&gt;
   b = getElementPosition(localPlayer)&lt;br /&gt;
end&lt;br /&gt;
stop = getTickCount()&lt;br /&gt;
print(&amp;quot;structural&amp;quot;, stop - start ) -- less then 200ms&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Useful_Classes&amp;diff=67400</id>
		<title>Template:Useful Classes</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Useful_Classes&amp;diff=67400"/>
		<updated>2020-09-21T15:47:05Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Useful Classes]]&lt;br /&gt;
*[[Singleton]] &amp;lt;span style=&amp;quot;color:gray; font-family:'Georgia',sans-serif; font-size:smaller;&amp;quot;&amp;gt;» This class allows to restrict the instantiation of a specific class to one object.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[CThread]] &amp;lt;span style=&amp;quot;color:gray; font-family:'Georgia',sans-serif; font-size:smaller;&amp;quot;&amp;gt;» This class represents a simple coroutine manager which can be used to limit method calls / loop.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[Importer]] &amp;lt;span style=&amp;quot;color:gray; font-family:'Georgia',sans-serif; font-size:smaller;&amp;quot;&amp;gt;» This class make easy to use exported functions.&amp;lt;/span&amp;gt;&lt;br /&gt;
*[[Observable]] &amp;lt;span style=&amp;quot;color:gray; font-family:'Georgia',sans-serif; font-size:smaller;&amp;quot;&amp;gt;» Observable variables. Call function on variable value change.&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Observable&amp;diff=67399</id>
		<title>Observable</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Observable&amp;diff=67399"/>
		<updated>2020-09-21T15:42:32Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;{{Useful Class}} __NOTOC__ This class allows you to watch for variables changes.  Call observable variable to push new state.  Author: CrosRoad95 Contact discord: mtasa.com/di...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Class}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This class allows you to watch for variables changes.&lt;br /&gt;
&lt;br /&gt;
Call observable variable to push new state.&lt;br /&gt;
&lt;br /&gt;
Author: CrosRoad95&lt;br /&gt;
Contact discord: mtasa.com/discord&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
OOP turn on&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
observable = {}&lt;br /&gt;
&lt;br /&gt;
function observable:onChange(callback)&lt;br /&gt;
	self.callback = callback&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function observable:__tostring()&lt;br /&gt;
	return self.value&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function observable:__call(newState)&lt;br /&gt;
	if(self.value == newState)then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	local oldValue = self.value;&lt;br /&gt;
	self.value = newState;&lt;br /&gt;
	if(self.callback)then&lt;br /&gt;
		self.callback(oldValue, self.value)&lt;br /&gt;
	end&lt;br /&gt;
	return true;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function observable:create(defaultValue)&lt;br /&gt;
	local t = { value = defaultValue, observators = {} }&lt;br /&gt;
	setmetatable(t, self)&lt;br /&gt;
	self.__index = self&lt;br /&gt;
	return t&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function watch(callback, ...)&lt;br /&gt;
	for i,v in ipairs({...})do&lt;br /&gt;
		v:onChange(function(old, new) &lt;br /&gt;
			if(callback)then&lt;br /&gt;
				callback(i, old, new)&lt;br /&gt;
			end&lt;br /&gt;
		end)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example 1==&lt;br /&gt;
How it works&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
a = observable:create(&amp;quot;asdf&amp;quot;) -- &amp;quot;asdf&amp;quot; is a default value.&lt;br /&gt;
b = observable:create(10)&lt;br /&gt;
&lt;br /&gt;
watch(function(index, prvValue, newValue) -- called every time observable value has change.&lt;br /&gt;
	print(&amp;quot;index&amp;quot;,index, &amp;quot;change&amp;quot;, prvValue, &amp;quot;=&amp;gt; &amp;quot;,newValue)&lt;br /&gt;
end, a, b) -- pass variables you want to watch&lt;br /&gt;
&lt;br /&gt;
a(20) -- index 1 change asdf =&amp;gt; 20&lt;br /&gt;
b(30) -- index 2 change 10 =&amp;gt; 30&lt;br /&gt;
a(&amp;quot;aaa&amp;quot;) -- index 1 change 20 =&amp;gt; aaa&lt;br /&gt;
&lt;br /&gt;
print(&amp;quot;value:&amp;quot;, a) -- in this case it will print &amp;quot;aaa&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Useful_Classes}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Importer&amp;diff=67398</id>
		<title>Importer</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Importer&amp;diff=67398"/>
		<updated>2020-09-21T15:35:23Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Useful Class}}&lt;br /&gt;
__NOTOC__&lt;br /&gt;
This function allow to import functions from other scripts.&lt;br /&gt;
Author: CrosRoad95&lt;br /&gt;
Contact discord: mtasa.com/discord&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
OOP turn on&lt;br /&gt;
&lt;br /&gt;
==Code==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
importer={}&lt;br /&gt;
importer.__index = importer&lt;br /&gt;
function importer:import(functionsToImport)&lt;br /&gt;
	assert(functionsToImport:len()&amp;gt;0,&amp;quot;specify what you want to import&amp;quot;)&lt;br /&gt;
	local impr = {}&lt;br /&gt;
	setmetatable(impr,importer)&lt;br /&gt;
	impr.scripts=functionsToImport&lt;br /&gt;
	return impr&lt;br /&gt;
end&lt;br /&gt;
function importer:from(script)&lt;br /&gt;
	local res=getResourceFromName(script)&lt;br /&gt;
	assert(res,&amp;quot;script doesnt exists&amp;quot;)&lt;br /&gt;
	local functions=res:getExportedFunctions()&lt;br /&gt;
	assert(#functions&amp;gt;0,&amp;quot;script must contain exports&amp;quot;)&lt;br /&gt;
	local importThis={}&lt;br /&gt;
	if(self.scripts==&amp;quot;*&amp;quot;)then&lt;br /&gt;
		importThis=functions&lt;br /&gt;
	else&lt;br /&gt;
		local tbsplit=split(self.scripts,&amp;quot;,&amp;quot;)&lt;br /&gt;
		for i,v in ipairs(functions)do&lt;br /&gt;
			for ii,vv in ipairs(tbsplit)do&lt;br /&gt;
				if(string.find(v,vv))then&lt;br /&gt;
					table.insert(importThis,v)&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	for i,v in ipairs(importThis)do&lt;br /&gt;
		_G[v]=function(...)&lt;br /&gt;
			return call(res,v,...)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
function import(...)&lt;br /&gt;
	return importer:import(...)&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example 1==&lt;br /&gt;
Import specified functions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
import(&amp;quot;function1,function2&amp;quot;):from(&amp;quot;myScript&amp;quot;) -- import functions &amp;quot;function1&amp;quot; and &amp;quot;function2&amp;quot; from script &amp;quot;myScript&amp;quot;&lt;br /&gt;
-- now &amp;quot;function1()&amp;quot; is same as &amp;quot;exports.myScript:function()&amp;quot;&lt;br /&gt;
function1(&amp;quot;test&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example 2==&lt;br /&gt;
Import functions which contain string&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
import(&amp;quot;function,otherFunctions&amp;quot;):from(&amp;quot;myScript&amp;quot;) -- import functions contain &amp;quot;function&amp;quot; in name, in this example import &amp;quot;function1&amp;quot; and &amp;quot;function2&amp;quot; from script &amp;quot;myScript&amp;quot;&lt;br /&gt;
function1(&amp;quot;test&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Example 3==&lt;br /&gt;
Import all functions&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
import(&amp;quot;*&amp;quot;):from(&amp;quot;myScript&amp;quot;) -- import all functions, in this example import &amp;quot;function1&amp;quot; and &amp;quot;function2&amp;quot; from script &amp;quot;myScript&amp;quot;&lt;br /&gt;
function1(&amp;quot;test&amp;quot;)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Useful_Classes}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsCreateWorld&amp;diff=67395</id>
		<title>PhysicsCreateWorld</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsCreateWorld&amp;diff=67395"/>
		<updated>2020-09-18T11:55:47Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
&lt;br /&gt;
{{Note|Availiable only in custom fork of mta. see https://github.com/multitheftauto/mtasa-blue/pull/1246 }}&lt;br /&gt;
&lt;br /&gt;
{{Client function}}&lt;br /&gt;
Creates physics world with default settings.&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
physics physicsCreateWorld( [ float gravityX, float gravityY, float gravityZ ] )             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''gravity:''' gravitation used for simulation. Default: 0,0, -9.81&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
*'''physics''' world used for simulation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
physics = physicsCreateWorld()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetMoonSize&amp;diff=66665</id>
		<title>GetMoonSize</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetMoonSize&amp;diff=66665"/>
		<updated>2020-05-20T17:07:22Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
{{New feature/item|3.0132|1.3.1|5063|&lt;br /&gt;
This function returns the moon size.&lt;br /&gt;
{{Note|The function will return ''false'' server-side if moon size has not been set before the function is called.}}&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
int getMoonSize ()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns a integer being the moon size that is currently set, depending on which side it is used.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
This example will tell the moon size to everyone when the resource is started.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function handleResourceStart( )&lt;br /&gt;
    outputChatBox( string.format( &amp;quot;Server's moon size is set to %d&amp;quot;, getMoonSize() ) )&lt;br /&gt;
end&lt;br /&gt;
addEventHandler( &amp;quot;onResourceStart&amp;quot;, resourceRoot, handleResourceStart )&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
{{Requirements|1.3.1-9.05063|1.3.1-9.05063}}&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client_world_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetRainLevel&amp;diff=66664</id>
		<title>GetRainLevel</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetRainLevel&amp;diff=66664"/>
		<updated>2020-05-20T17:06:05Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
This function is used to get the current rain level.&lt;br /&gt;
{{Note|The function will return ''false'' server-side if rain level has not been set before the function is called.}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
float getRainLevel( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns the rain level as a number.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
'''Example:''' Sets the rain (So it can detect it) before returning it. (In this case, when resource starts.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, getResourceRootElement(), function()&lt;br /&gt;
	setRainLevel(math.random(5))&lt;br /&gt;
end)&lt;br /&gt;
function returnRain()&lt;br /&gt;
	local rain = getRainlevel()&lt;br /&gt;
	if(rain &amp;gt;= 1) then&lt;br /&gt;
		outputChatBox(&amp;quot;Looks like it's going to be a rainy day!&amp;quot;,255,130,130,false)&lt;br /&gt;
	else&lt;br /&gt;
		outputChatBox(&amp;quot;Surprisingly dry!&amp;quot;,255,130,130,false)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;rain&amp;quot;, returnRain)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
'''Example:''' Sets the rain (So it can detect it) before returning it. (In this case, when resource starts.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, getResourceRootElement(), function()&lt;br /&gt;
	setRainLevel(math.random(5))&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
function returnRain(player)&lt;br /&gt;
	local rain = getRainlevel()&lt;br /&gt;
	if(rain &amp;gt;= 1) then&lt;br /&gt;
		outputChatBox(&amp;quot;Looks like it's going to be a rainy day!&amp;quot;,player,255,130,130,false)&lt;br /&gt;
	else&lt;br /&gt;
		outputChatBox(&amp;quot;Surprisingly dry!&amp;quot;,player,255,130,130,false)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;rain&amp;quot;, returnRain)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{World functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetRainLevel&amp;diff=66663</id>
		<title>GetRainLevel</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetRainLevel&amp;diff=66663"/>
		<updated>2020-05-20T17:05:51Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
This function is used to get the current rain level.&lt;br /&gt;
&lt;br /&gt;
{{Note|The function will return ''false'' server-side if sun size has not been set before the function is called.}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
float getRainLevel( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns the rain level as a number.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
&amp;lt;section name=&amp;quot;Client&amp;quot; class=&amp;quot;client&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
'''Example:''' Sets the rain (So it can detect it) before returning it. (In this case, when resource starts.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onClientResourceStart&amp;quot;, getResourceRootElement(), function()&lt;br /&gt;
	setRainLevel(math.random(5))&lt;br /&gt;
end)&lt;br /&gt;
function returnRain()&lt;br /&gt;
	local rain = getRainlevel()&lt;br /&gt;
	if(rain &amp;gt;= 1) then&lt;br /&gt;
		outputChatBox(&amp;quot;Looks like it's going to be a rainy day!&amp;quot;,255,130,130,false)&lt;br /&gt;
	else&lt;br /&gt;
		outputChatBox(&amp;quot;Surprisingly dry!&amp;quot;,255,130,130,false)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;rain&amp;quot;, returnRain)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;section name=&amp;quot;Server&amp;quot; class=&amp;quot;server&amp;quot; show=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
'''Example:''' Sets the rain (So it can detect it) before returning it. (In this case, when resource starts.)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEventHandler(&amp;quot;onResourceStart&amp;quot;, getResourceRootElement(), function()&lt;br /&gt;
	setRainLevel(math.random(5))&lt;br /&gt;
end)&lt;br /&gt;
&lt;br /&gt;
function returnRain(player)&lt;br /&gt;
	local rain = getRainlevel()&lt;br /&gt;
	if(rain &amp;gt;= 1) then&lt;br /&gt;
		outputChatBox(&amp;quot;Looks like it's going to be a rainy day!&amp;quot;,player,255,130,130,false)&lt;br /&gt;
	else&lt;br /&gt;
		outputChatBox(&amp;quot;Surprisingly dry!&amp;quot;,player,255,130,130,false)&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;rain&amp;quot;, returnRain)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/section&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{World functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetSunSize&amp;diff=66662</id>
		<title>GetSunSize</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetSunSize&amp;diff=66662"/>
		<updated>2020-05-20T17:04:45Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Server client function}}&lt;br /&gt;
This function is used to get the size of the sun.&lt;br /&gt;
{{Note|The function will return ''false'' server-side if sun size has not been set before the function is called.}}&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
float getSunSize ( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Returns the size of the sun as a number, false if the size of the sun is at its default.&lt;br /&gt;
&lt;br /&gt;
==Example== &lt;br /&gt;
This example lets any player get the size of the sun like /getsunsize&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function commandGetSunSize(player, command)&lt;br /&gt;
    local size = getSunSize()&lt;br /&gt;
    if (size) then&lt;br /&gt;
        outputChatBox(&amp;quot;The current size of the sun is &amp;quot;..size..&amp;quot;.&amp;quot;, player, 0, 255, 0)&lt;br /&gt;
    else&lt;br /&gt;
        outputChatBox(&amp;quot;The size of the sun is normal.&amp;quot;, player, 0, 255, 0)&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;getsunsize&amp;quot;, commandGetSunSize)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
==See Also==&lt;br /&gt;
{{World functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=GetWindVelocity&amp;diff=66661</id>
		<title>GetWindVelocity</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=GetWindVelocity&amp;diff=66661"/>
		<updated>2020-05-20T16:53:43Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
{{Server client function}}&lt;br /&gt;
This function gets the wind velocity in San Andreas.&lt;br /&gt;
{{Note|The function will return ''false'' server-side if wind velocity has not been set before the function is called.}}&lt;br /&gt;
==Syntax==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
int, int, int getWindVelocity ( )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
*'''velocityX''': The velocity on the x-coordinate or false if the wind velocity is default.&lt;br /&gt;
*'''velocityY''': The velocity on the y-coordinate or nil if the wind velocity is default.&lt;br /&gt;
*'''velocityZ''': The velocity on the z-coordinate or nil if the wind velocity is default.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
This example returns the wind velocity to a player if they use the command 'getwindvelocity'.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function commandGetWindVelocity(player, command)&lt;br /&gt;
   local vx, vy, vz = getWindVelocity()&lt;br /&gt;
   if (vx) then&lt;br /&gt;
       outputChatBox(&amp;quot;Wind Velocity X:&amp;quot;..vx..&amp;quot; Y:&amp;quot;..vy..&amp;quot; Z:&amp;quot;..vz, player, 255, 255, 0)&lt;br /&gt;
   else&lt;br /&gt;
       outputChatBox(&amp;quot;Wind velocity is default.&amp;quot;, player, 255, 255, 0)&lt;br /&gt;
   end&lt;br /&gt;
end&lt;br /&gt;
addCommandHandler(&amp;quot;getwindvelocity&amp;quot;, commandGetWindVelocity)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
{{Client_world_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=User:CrosRoad95&amp;diff=65217</id>
		<title>User:CrosRoad95</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=User:CrosRoad95&amp;diff=65217"/>
		<updated>2020-02-20T06:40:57Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;List of functions i'm working on:&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;br /&gt;
&lt;br /&gt;
Future ideas for physics:&lt;br /&gt;
# gear constraint&lt;br /&gt;
# wheels&lt;br /&gt;
# detailed raycast&lt;br /&gt;
# copying shape&lt;br /&gt;
# respawn point for rigid body, if will not activated for some time, got moved to respawn point&lt;br /&gt;
# attaching rigid body to mta object&lt;br /&gt;
# multimaterial triangle mesh&lt;br /&gt;
# options to build gta collision function:&lt;br /&gt;
## - what models should be created as rigid body, do they should have set respawn point?&lt;br /&gt;
## - reuse shapes, create new for duplicated models&lt;br /&gt;
## - don't create compound shape if not needed&lt;br /&gt;
# soft bodies&lt;br /&gt;
# drawing debug only for specified rigid body/static collision/shape&lt;br /&gt;
# debug mode to render only rigids, only static collision or both&lt;br /&gt;
# fast 3d line&lt;br /&gt;
# profiling&lt;br /&gt;
# quering physics element&lt;br /&gt;
# world size option to automatic get rid of rigid bodies which fall off world&lt;br /&gt;
# creating static or rigids collisions from objects created by createObject&lt;br /&gt;
# add rest of properties for everything&lt;br /&gt;
# improve current functions&lt;br /&gt;
## triangle mesh should accept `verteX, vertex, vertex, verteX, vertex, vertex` or {verteX, vertex, vertex, verteX, vertex, vertex,} or {{verteX, vertex, vertex}, {verteX, vertex, vertex}}&lt;br /&gt;
# multithreading physics simulation&lt;br /&gt;
# add missing shapes: btBox2dShape, btConvex2dShape, btEmptyShape, btGImpactCompoundShape, btGImpactMeshShape, btMinkowskiSumShape, CbtMultiSphereShape, CbtMultimaterialTriangleMeshShape, btPlaneShape, CbtScaledBvhTriangleMeshShape, &lt;br /&gt;
##&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=User:CrosRoad95&amp;diff=65216</id>
		<title>User:CrosRoad95</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=User:CrosRoad95&amp;diff=65216"/>
		<updated>2020-02-20T06:23:29Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;List of functions i'm working on:&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;br /&gt;
&lt;br /&gt;
Future ideas for physics:&lt;br /&gt;
# gear constraint&lt;br /&gt;
# wheels&lt;br /&gt;
# detailed raycast&lt;br /&gt;
# copying shape&lt;br /&gt;
# respawn point for rigid body??&lt;br /&gt;
# attaching rigid body to mta object&lt;br /&gt;
# multimaterial triangle mesh&lt;br /&gt;
# options to build gta collision function:&lt;br /&gt;
## - what models should be created as rigid body, do they should have set respawn point?&lt;br /&gt;
## - reuse shapes, create new for duplicated models&lt;br /&gt;
## - don't create compound shape if not needed&lt;br /&gt;
# soft bodies&lt;br /&gt;
# drawing debug only for specified rigid body/static collision/shape&lt;br /&gt;
# debug mode to render only rigids, only static collision or both&lt;br /&gt;
# fast 3d line&lt;br /&gt;
# profiling&lt;br /&gt;
# quering physics element&lt;br /&gt;
# world size option to automatic get rid of rigid bodies which fall off world&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Physics_properties&amp;diff=65215</id>
		<title>Physics properties</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Physics_properties&amp;diff=65215"/>
		<updated>2020-02-19T20:54:32Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Physics properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Physics properties===&lt;br /&gt;
used in&lt;br /&gt;
*[[physicsSetProperties]]&lt;br /&gt;
*[[physicsGetProperties]]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name || Support || Access || Parametrs || Description&lt;br /&gt;
|-&lt;br /&gt;
| mass || rigid-body || set, get || float mass || Changes mass of rigid body.&lt;br /&gt;
|-&lt;br /&gt;
| position || rigid-body, static-collision || set, get || float x, float y, float z || Sets/gets position.&lt;br /&gt;
|-&lt;br /&gt;
| position || constraint || get || float x, float y, float z || Returns avarge position of two rigids.&lt;br /&gt;
|-&lt;br /&gt;
| rotation || rigid-body, static-collision || set, get || float rx, float ry, float rz || Sets/gets rotation.&lt;br /&gt;
|-&lt;br /&gt;
| velocity || rigid-body || set, get || float velocityX, float velocityY, float velocityZ|| Sets/gets velocity.&lt;br /&gt;
|-&lt;br /&gt;
| angularvelocity || rigid-body || set, get || float velocityX, float velocityY, float velocityZ|| Sets/gets angular velocity.&lt;br /&gt;
|-&lt;br /&gt;
| sleepingthresholds || rigid-body || set, get || float velocity, float angularVelocity || Sets how slow rigid body have to move, to go sleep.&lt;br /&gt;
|-&lt;br /&gt;
| simulationenabled || physics-world || set, get || bool enabled = true || Enable/disable simulation.&lt;br /&gt;
|-&lt;br /&gt;
| simulationsubsteps || physics-world || set, get || int subSteps = 10 || Between 1 and 256, sets how long and how precise collision detection should be.&lt;br /&gt;
|-&lt;br /&gt;
| restitution || rigid-body || set, get || float value|| todo&lt;br /&gt;
|-&lt;br /&gt;
| scale || physics-shape, rigid-body, static-collision || set, get || float scaleX, float scaleY, float scaleZ || Sets/gets scale, if rigid of static collision as parametr, their shape scale got set/get. You can't scale per rigid/static collision&lt;br /&gt;
|-&lt;br /&gt;
| debugcolor || physics-shape, rigid-body, static-collision || set, get || color theColor / boolean false resets color || Changes debug color&lt;br /&gt;
|-&lt;br /&gt;
| filtermask || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| filtergroup || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| stiffness|| todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| size || shape|| set, get || float sizeX, float sizeY, float sizeZ || Changes size of &amp;quot;box&amp;quot; shape type.&lt;br /&gt;
|-&lt;br /&gt;
| radius || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| height || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| boundingbox || todo || get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| boundingsphere || todo || get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| gravity || physics-world || set, get || float gravityX, float gravityY, float gravityZ|| Changes gravity of the simulation&lt;br /&gt;
|-&lt;br /&gt;
| usecontinuous || physics-world || set, get || bool bEnabled || False by default, enable detection of rigid body which happened between two simulation steps. Cause increased simulation time, prevents small shapes fly through thick surfaces&lt;br /&gt;
|-&lt;br /&gt;
| motionthreshold || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| sweptsphereradius || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| pivota || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| pivotb || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| lowerlinlimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| upperlinlimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| loweranglimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| upperanglimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| breakingimpulsethreshold || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| appliedimpulse || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| jointfeedback || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| constraintbroken || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| triggercollisionevents || physics-world || set, get || bool bEnabled = false || Cause physics world starts to trigger collision events. Don't enable if you don't use them. Can cause spam.&lt;br /&gt;
|-&lt;br /&gt;
| triggerconstraintevents || physics-world || set, get || bool bEnabled = false ||  Cause physics world starts to trigger constraints events. Don't enable if you don't use them. Can cause spam.&lt;br /&gt;
|-&lt;br /&gt;
| rigidbodya || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| rigidbodyb|| todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| sleep || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| wantssleeping || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| iscompound || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| iscocave || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isconvex || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isconvex2d || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isinfinite || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isnonmoving || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| ispolyhedral || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| issoftbody || todo || set, get || todo || todo&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsIsElement&amp;diff=65214</id>
		<title>PhysicsIsElement</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsIsElement&amp;diff=65214"/>
		<updated>2020-02-19T19:16:14Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;__NOTOC__  {{Client function}} Returns whatever physics-element exists  ==Syntax==  &amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt; bool physicsIsElement(physics-element thePhysicsElement)...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Returns whatever physics-element exists&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool physicsIsElement(physics-element thePhysicsElement)             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePhysicsElement:''' physics element: shape, constraint, rigid body, static collision&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
True if physics element exists&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
if shape got destroyed, static collisions, rigid body and its constraints will destroyed too, this example prove it.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local shape = physicsCreateShape(physics, &amp;quot;box&amp;quot;, 1)&lt;br /&gt;
local rb = physicsCreateRigidBody(shape)&lt;br /&gt;
local col = physicsCreateStaticCollision(shape)&lt;br /&gt;
local const = physicsCreateConstraint(&amp;quot;pointtopoint&amp;quot;, rb, 0,0,0)&lt;br /&gt;
iprint(&amp;quot;isElement before&amp;quot;, physicsIsElement(shape), physicsIsElement(rb), physicsIsElement(col), physicsIsElement(const)) -- true, true, true, true&lt;br /&gt;
physicsDestroy(shape)&lt;br /&gt;
iprint(&amp;quot;isElement after&amp;quot;, physicsIsElement(shape), physicsIsElement(rb), physicsIsElement(col), physicsIsElement(const)) -- false, false, false ,false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Client_physics_functions&amp;diff=65213</id>
		<title>Template:Client physics functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Client_physics_functions&amp;diff=65213"/>
		<updated>2020-02-19T19:13:50Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*[[physicsCreateWorld]]&lt;br /&gt;
*[[physicsDestroy]]&lt;br /&gt;
*[[physicsCreateShape]]&lt;br /&gt;
*[[physicsCreateShapeFromModel]]&lt;br /&gt;
*[[physicsCreateRigidBody]]&lt;br /&gt;
*[[physicsCreateStaticCollision]]&lt;br /&gt;
*[[physicsCreateConstraint]]&lt;br /&gt;
*[[physicsAddChildShape]]&lt;br /&gt;
*[[physicsRemoveChildShape]]&lt;br /&gt;
*[[physicsGetChildShapes]]&lt;br /&gt;
*[[physicsSetChildShapeOffsets]]&lt;br /&gt;
*[[physicsGetChildShapeOffsets]]&lt;br /&gt;
*[[physicsGetShapes]]&lt;br /&gt;
*[[physicsGetRigidBodies]]&lt;br /&gt;
*[[physicsGetStaticCollisions]]&lt;br /&gt;
*[[physicsGetConstraints]]&lt;br /&gt;
*[[physicsSetProperties]]&lt;br /&gt;
*[[physicsGetProperties]]&lt;br /&gt;
*[[physicsDrawDebug]]&lt;br /&gt;
*[[physicsSetDebugMode]]&lt;br /&gt;
*[[physicsBuildCollisionFromGTA]]&lt;br /&gt;
*[[physicsApplyVelocity]]&lt;br /&gt;
*[[physicsApplyVelocityForce]]&lt;br /&gt;
*[[physicsApplyAngularVelocity]]&lt;br /&gt;
*[[physicsApplyAngularVelocityForce]]&lt;br /&gt;
*[[physicsApplyDamping]]&lt;br /&gt;
*[[physicsRayCast]]&lt;br /&gt;
*[[physicsShapeCast]]&lt;br /&gt;
*[[physicsGetElementType]]&lt;br /&gt;
*[[physicsIsElement]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsGetElementType&amp;diff=65212</id>
		<title>PhysicsGetElementType</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsGetElementType&amp;diff=65212"/>
		<updated>2020-02-19T19:11:58Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Returns type of physics-element&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
string physicsGetElementType(physics-element thePhysicsElement)             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePhysicsElement:''' physics element: shape, constraint, rigid body, static collision&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Name of physics element, &amp;quot;shape&amp;quot;, &amp;quot;rigidbody&amp;quot;, &amp;quot;staticcollision&amp;quot;, &amp;quot;constraint&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local shape = physicsCreateShape(physics, &amp;quot;box&amp;quot;, 1)&lt;br /&gt;
local rb = physicsCreateRigidBody(shape)&lt;br /&gt;
local col = physicsCreateStaticCollision(shape)&lt;br /&gt;
local const = physicsCreateConstraint(&amp;quot;pointtopoint&amp;quot;, rb, 0,0,0)&lt;br /&gt;
iprint(&amp;quot;shape: &amp;quot;,physicsGetElementType(shape)) -- shape&lt;br /&gt;
iprint(&amp;quot;rigidbody: &amp;quot;,physicsGetElementType(rb)) -- rigidbody&lt;br /&gt;
iprint(&amp;quot;staticcollision: &amp;quot;,physicsGetElementType(col)) -- staticcollision&lt;br /&gt;
iprint(&amp;quot;constraint: &amp;quot;,physicsGetElementType(const)) -- constraint&lt;br /&gt;
iprint(&amp;quot;invalid: &amp;quot;,physicsGetElementType(physics)) -- false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsGetElementType&amp;diff=65211</id>
		<title>PhysicsGetElementType</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsGetElementType&amp;diff=65211"/>
		<updated>2020-02-19T19:05:07Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;__NOTOC__  {{Client function}} Returns type of physics-element  ==Syntax==  &amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt; string physicsGetElementType(physics-element thePhysicsElement)...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Returns type of physics-element&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
string physicsGetElementType(physics-element thePhysicsElement)             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePhysicsElement:''' physics element: shape, constraint, rigid body, static collision&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
Name of physics element, &amp;quot;shape&amp;quot;, &amp;quot;rigidbody&amp;quot;, &amp;quot;staticcollision&amp;quot;, &amp;quot;constraint&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local shape = physicsCreateShape(physics, &amp;quot;box&amp;quot;, 1)&lt;br /&gt;
local rb = physicsCreateRigidBody(shape)&lt;br /&gt;
local col = physicsCreateStaticCollision(shape)&lt;br /&gt;
local const = physicsCreateConstraint(&amp;quot;pointtopoint&amp;quot;, rb, 0,0,0)&lt;br /&gt;
iprint(&amp;quot;shape: &amp;quot;,physicsGetElementType(shape)) -- shape&lt;br /&gt;
iprint(&amp;quot;rigidbody: &amp;quot;,physicsGetElementType(shape)) -- rigidbody&lt;br /&gt;
iprint(&amp;quot;staticcollision: &amp;quot;,physicsGetElementType(col)) -- staticcollision&lt;br /&gt;
iprint(&amp;quot;constraint: &amp;quot;,physicsGetElementType(const)) -- constraint&lt;br /&gt;
iprint(&amp;quot;invalid: &amp;quot;,physicsGetElementType(physics)) -- false&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Template:Client_physics_functions&amp;diff=65210</id>
		<title>Template:Client physics functions</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Template:Client_physics_functions&amp;diff=65210"/>
		<updated>2020-02-19T19:02:25Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*[[physicsCreateWorld]]&lt;br /&gt;
*[[physicsDestroy]]&lt;br /&gt;
*[[physicsCreateShape]]&lt;br /&gt;
*[[physicsCreateShapeFromModel]]&lt;br /&gt;
*[[physicsCreateRigidBody]]&lt;br /&gt;
*[[physicsCreateStaticCollision]]&lt;br /&gt;
*[[physicsCreateConstraint]]&lt;br /&gt;
*[[physicsAddChildShape]]&lt;br /&gt;
*[[physicsRemoveChildShape]]&lt;br /&gt;
*[[physicsGetChildShapes]]&lt;br /&gt;
*[[physicsSetChildShapeOffsets]]&lt;br /&gt;
*[[physicsGetChildShapeOffsets]]&lt;br /&gt;
*[[physicsGetShapes]]&lt;br /&gt;
*[[physicsGetRigidBodies]]&lt;br /&gt;
*[[physicsGetStaticCollisions]]&lt;br /&gt;
*[[physicsGetConstraints]]&lt;br /&gt;
*[[physicsSetProperties]]&lt;br /&gt;
*[[physicsGetProperties]]&lt;br /&gt;
*[[physicsDrawDebug]]&lt;br /&gt;
*[[physicsSetDebugMode]]&lt;br /&gt;
*[[physicsBuildCollisionFromGTA]]&lt;br /&gt;
*[[physicsApplyVelocity]]&lt;br /&gt;
*[[physicsApplyVelocityForce]]&lt;br /&gt;
*[[physicsApplyAngularVelocity]]&lt;br /&gt;
*[[physicsApplyAngularVelocityForce]]&lt;br /&gt;
*[[physicsApplyDamping]]&lt;br /&gt;
*[[physicsRayCast]]&lt;br /&gt;
*[[physicsShapeCast]]&lt;br /&gt;
*[[physicsGetElementType]]&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Physics_properties&amp;diff=65207</id>
		<title>Physics properties</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Physics_properties&amp;diff=65207"/>
		<updated>2020-02-19T15:54:58Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Physics properties */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Physics properties===&lt;br /&gt;
used in&lt;br /&gt;
*[[physicsSetProperties]]&lt;br /&gt;
*[[physicsGetProperties]]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name || Support || Access || Parametrs || Description&lt;br /&gt;
|-&lt;br /&gt;
| mass || rigid-body || set, get || float mass || Changes mass of rigid body.&lt;br /&gt;
|-&lt;br /&gt;
| position || rigid-body, static-collision || set, get || float x, float y, float z || Sets/gets position.&lt;br /&gt;
|-&lt;br /&gt;
| position || constraint || get || float x, float y, float z || Returns avarge position of two rigids.&lt;br /&gt;
|-&lt;br /&gt;
| rotation || rigid-body, static-collision || set, get || float rx, float ry, float rz || Sets/gets rotation.&lt;br /&gt;
|-&lt;br /&gt;
| velocity || rigid-body || set, get || float velocityX, float velocityY, float velocityZ|| Sets/gets velocity.&lt;br /&gt;
|-&lt;br /&gt;
| angularvelocity || rigid-body || set, get || float velocityX, float velocityY, float velocityZ|| Sets/gets angular velocity.&lt;br /&gt;
|-&lt;br /&gt;
| sleepingthresholds || rigid-body || set, get || float velocity, float angularVelocity || Sets how slow rigid body have to move, to go sleep.&lt;br /&gt;
|-&lt;br /&gt;
| simulationenabled || physics-world || set, get || bool enabled = true || Enable/disable simulation.&lt;br /&gt;
|-&lt;br /&gt;
| restitution || rigid-body || set, get || float value|| todo&lt;br /&gt;
|-&lt;br /&gt;
| scale || physics-shape, rigid-body, static-collision || set, get || float scaleX, float scaleY, float scaleZ || Sets/gets scale&lt;br /&gt;
|-&lt;br /&gt;
| debugcolor || physics-shape, rigid-body, static-collision || set, get || color theColor / boolean false resets color || Changes debug color&lt;br /&gt;
|-&lt;br /&gt;
| filtermask || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| filtergroup || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| stiffness|| todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| size || shape|| set, get || float sizeX, float sizeY, float sizeZ || Changes size of &amp;quot;box&amp;quot; shape type.&lt;br /&gt;
|-&lt;br /&gt;
| radius || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| height || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| boundingbox || todo || get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| boundingsphere || todo || get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| gravity || physics-world || set, get || float gravityX, float gravityY, float gravityZ|| Changes gravity of the simulation&lt;br /&gt;
|-&lt;br /&gt;
| usecontinuous || physics-world || set, get || bool bEnabled || False by default, enable detection of rigid body which happened between two simulation steps. Cause increased simulation time, prevents small shapes fly through thick surfaces&lt;br /&gt;
|-&lt;br /&gt;
| motionthreshold || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| sweptsphereradius || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| pivota || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| pivotb || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| lowerlinlimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| upperlinlimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| loweranglimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| upperanglimit || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| breakingimpulsethreshold || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| appliedimpulse || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| jointfeedback || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| constraintbroken || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| triggercollisionevents || physics-world || set, get || bool bEnabled = false || Cause physics world starts to trigger collision events. Don't enable if you don't use them. Can cause spam.&lt;br /&gt;
|-&lt;br /&gt;
| triggerconstraintevents || physics-world || set, get || bool bEnabled = false ||  Cause physics world starts to trigger constraints events. Don't enable if you don't use them. Can cause spam.&lt;br /&gt;
|-&lt;br /&gt;
| rigidbodya || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| rigidbodyb|| todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| sleep || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| wantssleeping || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| iscompound || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| iscocave || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isconvex || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isconvex2d || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isinfinite || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| isnonmoving || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| ispolyhedral || todo || set, get || todo || todo&lt;br /&gt;
|-&lt;br /&gt;
| issoftbody || todo || set, get || todo || todo&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsBuildCollisionFromGTA&amp;diff=65206</id>
		<title>PhysicsBuildCollisionFromGTA</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsBuildCollisionFromGTA&amp;diff=65206"/>
		<updated>2020-02-19T15:17:58Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;__NOTOC__  {{Client function}} Makes gta collision get copied into bullet physics collision world. Doesn't load areas thats are not streamed in ( don't have loaded collisions...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Makes gta collision get copied into bullet physics collision world.&lt;br /&gt;
Doesn't load areas thats are not streamed in ( don't have loaded collisions )&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
bool physicsBuildCollisionFromGTA( physics thePhysics, [float x, float y, float z, float radius ] )             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''x, y, z, radius:''' area you want to load.&lt;br /&gt;
&lt;br /&gt;
If position and radius passed, only this area got loaded, if not, flag got set to automatically scan all gta models every short period of time and load it for you.&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
True if success, false otherwise&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsCreateConstraint&amp;diff=65203</id>
		<title>PhysicsCreateConstraint</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsCreateConstraint&amp;diff=65203"/>
		<updated>2020-02-19T15:10:55Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: Created page with &amp;quot;__NOTOC__  {{Client function}} Creates connection between rigid body and other rigid body or specified position.  ==Syntax==  &amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt; physics-constraint p...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Creates connection between rigid body and other rigid body or specified position.&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
physics-constraint physicsCreateConstraint(constraint-type theConstraintType [, disableCollisionsBetweenLinkedBodies = true], physics-rigid-body rigidBodyA [, physics-rigid-body rigidBodyB], mixed )             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''theConstraintType:''' &amp;quot;pointtopoint&amp;quot;, &amp;quot;hidge&amp;quot;, &amp;quot;fixed&amp;quot;, &amp;quot;slider&amp;quot;, see [[Physics constraints]]&lt;br /&gt;
*'''disableCollisionsBetweenLinkedBodies:''' disable collision between two rigid bodies, useful when rigids are close to each other.&lt;br /&gt;
*'''rigidBodyA:''' first rigid body,&lt;br /&gt;
*'''rigidBodyB:''' second rigid body, optional, can be replaced with position in some cases.&lt;br /&gt;
*'''mixed:''' depends on constraint type&lt;br /&gt;
===Returns===&lt;br /&gt;
*'''physics''' world used for simulation.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Spawns capsule and attach invisible line to the rigid body.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local capsule = physicsCreateShape(physics, &amp;quot;capsule&amp;quot;, 0.5, 1.2)&lt;br /&gt;
local capsulerb = physicsCreateRigidBody(capsule );&lt;br /&gt;
physicsCreateConstraint(&amp;quot;pointtopoint&amp;quot;, capsulerb, 0,0,0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsCreateShapeFromModel&amp;diff=65196</id>
		<title>PhysicsCreateShapeFromModel</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsCreateShapeFromModel&amp;diff=65196"/>
		<updated>2020-02-19T14:34:00Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Creates shape from model in specific physics world. Model must be streamed in ( orignal gtasa models counts as stream in )&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
physics-shape physicsCreateShapeFromModel(physics thePhysics, int model)             &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePhysics:''' Physics world.&lt;br /&gt;
*'''model:''' object model.&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
*'''shape''' compound shape made of triangle mesh, boxes and spheres.&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
Spawns hay, tree, barn, hay stack and fence as rigid body near by 0,0,0 coords&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
function createRigidBodyFromModel(model, x, y, z)&lt;br /&gt;
  local shape = physicsCreateShapeFromModel(physics, model)&lt;br /&gt;
  if(shape)then&lt;br /&gt;
    local rigid = physicsCreateRigidBody(shape)&lt;br /&gt;
    physicsSetProperties(rigid, &amp;quot;position&amp;quot;,  x, y, z)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
createRigidBodyFromModel(3276, 0,0,10)&lt;br /&gt;
createRigidBodyFromModel(672, 20,0,10)&lt;br /&gt;
createRigidBodyFromModel(12918, -20,0,10)&lt;br /&gt;
createRigidBodyFromModel(3374, 0,20,10)&lt;br /&gt;
createRigidBodyFromModel(12919, 0,-30,10)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsCreateShape&amp;diff=65190</id>
		<title>PhysicsCreateShape</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsCreateShape&amp;diff=65190"/>
		<updated>2020-02-18T21:30:53Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Creates physics shape used for static or dynamic collision detection&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, shape-type theShapeType, mixed)&lt;br /&gt;
         &lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;box&amp;quot;, float size)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;box&amp;quot;, float sizeX, sizeY, sizeZ)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;sphere&amp;quot;, float radius)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;capsule&amp;quot;, float radius, float height)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;cone&amp;quot;, float radius, float height)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;cylinder&amp;quot;, float radius, float height)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;heightfieldterrain&amp;quot;, int sizeX, int sizeY [, table heightData ] )&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;compound&amp;quot;, int initialChildCapacity = 0)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;trianglemesh&amp;quot;, vector3 vertexA, vector3 vertexB, vector3 vertexC, ...)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;convexhull&amp;quot;, vector3 pointA, vector3 pointB, vector3, pointC, ...)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''heightfieldterrain:''' minimum size is 3x3, and maximum 8192x8192. By default terrain is flat, you can pass default height after size, each float represents height of next vertex.&lt;br /&gt;
*'''trianglemesh:''' each of three vectors creates single triangle, use n*3 vectors to create n triangles.&lt;br /&gt;
*'''compound:''' can contain up to 8192 child shapes.&lt;br /&gt;
*'''convexhull:''' require at least 3 points.&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePhysics:''' physics world&lt;br /&gt;
*'''theShapeType:''' shape, availiable types &amp;quot;box&amp;quot;, &amp;quot;sphere&amp;quot;, &amp;quot;capsule&amp;quot;, &amp;quot;cone&amp;quot;, &amp;quot;cylinder&amp;quot;, &amp;quot;heightfieldterrain&amp;quot;, &amp;quot;compound&amp;quot;, &amp;quot;trianglemesh&amp;quot;, &amp;quot;convexhull&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
*'''physics-shape''' to use in future functions&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local terrainData = {&lt;br /&gt;
  3,3,3,3,&lt;br /&gt;
  3,0,0,3,&lt;br /&gt;
  3,0,0,3,&lt;br /&gt;
  3,3,3,3,&lt;br /&gt;
}&lt;br /&gt;
local terrainShape = physicsCreateShape(physics, &amp;quot;heightfieldterrain&amp;quot;, 4,4, terrainData)&lt;br /&gt;
local terrain = physicsCreateStaticCollision(terrainShape)&lt;br /&gt;
physicsSetProperties(terrain, &amp;quot;position&amp;quot;, 0,0,5)&lt;br /&gt;
physicsSetProperties(terrain, &amp;quot;scale&amp;quot;, 5,5,1) -- in terrain, sets mesh density, now mesh has size 20x20units, one vertex every 5 units&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=PhysicsCreateShape&amp;diff=65189</id>
		<title>PhysicsCreateShape</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=PhysicsCreateShape&amp;diff=65189"/>
		<updated>2020-02-18T20:41:10Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
{{Client function}}&lt;br /&gt;
Creates physics shape used for static or dynamic collision detection&lt;br /&gt;
&lt;br /&gt;
==Syntax== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, shape-type theShapeType, mixed)&lt;br /&gt;
         &lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;box&amp;quot;, float size)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;box&amp;quot;, float sizeX, sizeY, sizeZ)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;sphere&amp;quot;, float radius)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;capsule&amp;quot;, float radius, float height)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;cone&amp;quot;, float radius, float height)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;cylinder&amp;quot;, float radius, float height)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;heightfieldterrain&amp;quot;, int sizeX, int sizeY [, float height,float height, ... )&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;compound&amp;quot;, int initialChildCapacity = 0)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;trianglemesh&amp;quot;, vector3 vertexA, vector3 vertexB, vector3 vertexC, ...)&lt;br /&gt;
physics-shape physicsCreateShape(physics thePhysics, &amp;quot;convexhull&amp;quot;, vector3 pointA, vector3 pointB, vector3, pointC, ...)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''heightfieldterrain:''' minimum size is 3x3, and maximum 8192x8192. By default terrain is flat, you can pass default height after size, each float represents height of next vertex.&lt;br /&gt;
*'''trianglemesh:''' each of three vectors creates single triangle, use n*3 vectors to create n triangles.&lt;br /&gt;
*'''compound:''' can contain up to 8192 child shapes.&lt;br /&gt;
*'''convexhull:''' require at least 3 points.&lt;br /&gt;
&lt;br /&gt;
===Required Arguments=== &lt;br /&gt;
*'''thePhysics:''' physics world&lt;br /&gt;
*'''theShapeType:''' shape, availiable types &amp;quot;box&amp;quot;, &amp;quot;sphere&amp;quot;, &amp;quot;capsule&amp;quot;, &amp;quot;cone&amp;quot;, &amp;quot;cylinder&amp;quot;, &amp;quot;heightfieldterrain&amp;quot;, &amp;quot;compound&amp;quot;, &amp;quot;trianglemesh&amp;quot;, &amp;quot;convexhull&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
===Returns===&lt;br /&gt;
*'''physics-shape''' to use in future functions&lt;br /&gt;
&lt;br /&gt;
==Example==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
&lt;br /&gt;
{{Client_physics_functions}}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Physics_debug_mode&amp;diff=65186</id>
		<title>Physics debug mode</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Physics_debug_mode&amp;diff=65186"/>
		<updated>2020-02-18T17:34:35Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Physics debug modes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Physics debug modes===&lt;br /&gt;
used in&lt;br /&gt;
*[[physicsSetDebugMode]]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name || Parametrs || Description&lt;br /&gt;
|-&lt;br /&gt;
| nodebug || bool || If set to true, disable all debug modes&lt;br /&gt;
|-&lt;br /&gt;
| drawwireframe || bool || enables/disables wireframe rendering&lt;br /&gt;
|-&lt;br /&gt;
| drawaabb|| bool || shows bounding boxes of rigid bodies and static collisions&lt;br /&gt;
|-&lt;br /&gt;
| drawfeaturestext || bool || todo, not implemented yet&lt;br /&gt;
|-&lt;br /&gt;
| drawcontactpoints || bool || draws little yellow lines in points of contact&lt;br /&gt;
|-&lt;br /&gt;
| nodeactivation || bool || cause all rigid bodies are all time activated&lt;br /&gt;
|-&lt;br /&gt;
| nohelptext || bool || todo, not implemented yet&lt;br /&gt;
|-&lt;br /&gt;
| drawtext || bool || todo, not implemented yet&lt;br /&gt;
|-&lt;br /&gt;
| profiletimings || bool || todo, not implemented yet&lt;br /&gt;
|-&lt;br /&gt;
| enablesatcomparison || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| disablebulletlcp || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| enableccd || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawconstraints || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawconstraintlimits || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| fastwireframe || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawnormals || bool || draws normals&lt;br /&gt;
|-&lt;br /&gt;
| drawframes || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| linewidth || float || changes width of debugging line&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
	<entry>
		<id>https://wiki.multitheftauto.com/index.php?title=Physics_debug_mode&amp;diff=65185</id>
		<title>Physics debug mode</title>
		<link rel="alternate" type="text/html" href="https://wiki.multitheftauto.com/index.php?title=Physics_debug_mode&amp;diff=65185"/>
		<updated>2020-02-18T17:24:54Z</updated>

		<summary type="html">&lt;p&gt;CrosRoad95: /* Physics debug modes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Physics debug modes===&lt;br /&gt;
used in&lt;br /&gt;
*[[physicsSetDebugMode]]&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name || Parametrs || Description&lt;br /&gt;
|-&lt;br /&gt;
| nodebug || bool || If set to true, disable all debug modes&lt;br /&gt;
|-&lt;br /&gt;
| drawwireframe || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawaabb|| bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawfeaturestext || bool || todo, not implemented yet&lt;br /&gt;
|-&lt;br /&gt;
| drawcontactpoints || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| nodeactivation || bool || cause all rigid bodies are all time activated&lt;br /&gt;
|-&lt;br /&gt;
| nohelptext || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawtext || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| profiletimings || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| enablesatcomparison || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| disablebulletlcp || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| enableccd || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawconstraints || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawconstraintlimits || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| fastwireframe || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| drawnormals || bool || draws normals&lt;br /&gt;
|-&lt;br /&gt;
| drawframes || bool || todo&lt;br /&gt;
|-&lt;br /&gt;
| linewidth || float || changes width of debugging line&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>CrosRoad95</name></author>
	</entry>
</feed>