diff --git a/cl_plate_reader.lua b/cl_plate_reader.lua index dbcd26d..2dff9ca 100644 --- a/cl_plate_reader.lua +++ b/cl_plate_reader.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -36,34 +36,34 @@ READER = {} Plate reader variables NOTE - This is not a config, do not touch anything unless you know what - you are actually doing. + you are actually doing. ----------------------------------------------------------------------------------]]-- -READER.vars = +READER.vars = { - -- Whether or not the plate reader's UI is visible + -- Whether or not the plate reader's UI is visible displayed = false, -- Whether or not the plate reader should be hidden, e.g. the display is active but the player then steps -- out of their vehicle hidden = false, - -- The BOLO plate - boloPlate = "", - - -- Cameras, this table contains all of the data needed for operation of the front and rear plate reader + -- The BOLO plate + boloPlate = "", + + -- Cameras, this table contains all of the data needed for operation of the front and rear plate reader cams = { -- Variables for the front camera ["front"] = { plate = "", -- The current plate caught by the reader index = "", -- The index of the current plate - locked = false -- If the reader is locked - }, + locked = false -- If the reader is locked + }, -- Variables for the rear camera ["rear"] = { plate = "", -- The current plate caught by the reader index = "", -- The index of the current plate - locked = false -- If the reader is locked + locked = false -- If the reader is locked } } } @@ -71,143 +71,143 @@ READER.vars = -- Gets the display state function READER:GetDisplayState() return self.vars.displayed -end +end -- Toggles the display state of the plate reader system function READER:ToggleDisplayState() - -- Toggle the display variable - self.vars.displayed = not self.vars.displayed + -- Toggle the display variable + self.vars.displayed = not self.vars.displayed - -- Send the toggle message to the NUI side + -- Send the toggle message to the NUI side SendNUIMessage( { _type = "setReaderDisplayState", state = self:GetDisplayState() } ) -end +end --- Sets the display's hidden state to the given state +-- Sets the display's hidden state to the given state function READER:SetDisplayHidden( state ) - self.vars.hidden = state -end + self.vars.hidden = state +end --- Returns if the display is hidden +-- Returns if the display is hidden function READER:GetDisplayHidden() - return self.vars.hidden + return self.vars.hidden end -- Returns the stored plate for the given reader function READER:GetPlate( cam ) - return self.vars.cams[cam].plate -end + return self.vars.cams[cam].plate +end --- Sets the plate for the given reader to the given plate +-- Sets the plate for the given reader to the given plate function READER:SetPlate( cam, plate ) - self.vars.cams[cam].plate = plate -end + self.vars.cams[cam].plate = plate +end -- Returns the stored plate index for the given reader function READER:GetIndex( cam ) return self.vars.cams[cam].index -end +end -- Sets the plate index for the given reader to the given index function READER:SetIndex( cam, index ) - self.vars.cams[cam].index = index -end + self.vars.cams[cam].index = index +end -- Returns the bolo plate function READER:GetBoloPlate() - if ( self.vars.boloPlate ~= nil ) then + if ( self.vars.boloPlate ~= nil ) then return self.vars.boloPlate - end -end + end +end --- Sets the bolo plate to the given plate +-- Sets the bolo plate to the given plate function READER:SetBoloPlate( plate ) self.vars.boloPlate = plate UTIL:Notify( "BOLO plate set to: ~b~" .. plate ) -end +end --- Clears the BOLO plate +-- Clears the BOLO plate function READER:ClearBoloPlate() - self.vars.boloPlate = nil + self.vars.boloPlate = nil UTIL:Notify( "~b~BOLO plate cleared!" ) -end +end -- Returns if the given reader is locked function READER:GetCamLocked( cam ) return self.vars.cams[cam].locked -end +end -- Locks the given reader function READER:LockCam( cam, playBeep, isBolo ) -- Check that plate readers can actually be locked - if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then - -- Toggle the lock state + if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then + -- Toggle the lock state self.vars.cams[cam].locked = not self.vars.cams[cam].locked - -- Tell the NUI side to show/hide the lock icon + -- Tell the NUI side to show/hide the lock icon SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ), isBolo = isBolo } ) - -- Play a beep - if ( self:GetCamLocked( cam ) ) then - if ( playBeep ) then + -- Play a beep + if ( self:GetCamLocked( cam ) ) then + if ( playBeep ) then SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "plateAudio" ) } ) - end + end - if ( isBolo ) then + if ( isBolo ) then SendNUIMessage( { _type = "audio", name = "plate_hit", vol = RADAR:GetSettingValue( "plateAudio" ) } ) - end - + end + -- Trigger an event so developers can hook into the scanner every time a plate is locked TriggerServerEvent( "wk:onPlateLocked", cam, self:GetPlate( cam ), self:GetIndex( cam ) ) - end - end -end + end + end +end -- Returns if the plate reader system can perform tasks function READER:CanPerformMainTask() return self.vars.displayed and not self.vars.hidden -end +end --- Returns if the given relative position value is for front or rear +-- Returns if the given relative position value is for front or rear function READER:GetCamFromNum( relPos ) - if ( relPos == 1 ) then + if ( relPos == 1 ) then return "front" - elseif ( relPos == -1 ) then + elseif ( relPos == -1 ) then return "rear" - end -end + end +end RegisterNetEvent( "wk:togglePlateLock" ) AddEventHandler( "wk:togglePlateLock", function( cam, beep, bolo ) READER:LockCam( cam, beep, bolo ) end ) --- Runs when the "Toggle Display" button is pressed on the plate reder box +-- Runs when the "Toggle Display" button is pressed on the plate reder box RegisterNUICallback( "togglePlateReaderDisplay", function( data, cb ) - -- Toggle the display state + -- Toggle the display state READER:ToggleDisplayState() - cb( "ok" ) + cb( "ok" ) end ) -- Runs when the "Set BOLO Plate" button is pressed on the plate reader box RegisterNUICallback( "setBoloPlate", function( plate, cb ) - -- Set the BOLO plate + -- Set the BOLO plate READER:SetBoloPlate( plate ) - cb( "ok" ) + cb( "ok" ) end ) -- Runs when the "Clear BOLO Plate" button is pressed on the plate reader box RegisterNUICallback( "clearBoloPlate", function( plate, cb ) - -- Clear the BOLO plate + -- Clear the BOLO plate READER:ClearBoloPlate() cb( "ok" ) end ) -- This is the main function that runs and scans all vehicles in front and behind the patrol vehicle function READER:Main() - -- Check that the system can actually run - if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then + -- Check that the system can actually run + if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then -- Loop through front (1) and rear (-1) - for i = 1, -1, -2 do + for i = 1, -1, -2 do -- Get the world position of the player's vehicle local pos = GetEntityCoords( PLY.veh ) @@ -217,14 +217,14 @@ function READER:Main() -- Get the end position 50m in front/behind the player's vehicle local offset = GetOffsetFromEntityInWorldCoords( PLY.veh, -2.5, ( 50.0 * i ), 0.0 ) - -- Run the ray trace to get a vehicle + -- Run the ray trace to get a vehicle local veh = UTIL:GetVehicleInDirection( PLY.veh, start, offset ) -- Get the plate reader text for front/rear local cam = self:GetCamFromNum( i ) - + -- Only proceed to read a plate if the hit entity is a valid vehicle and the current camera isn't locked - if ( DoesEntityExist( veh ) and IsEntityAVehicle( veh ) and not self:GetCamLocked( cam ) ) then + if ( DoesEntityExist( veh ) and IsEntityAVehicle( veh ) and not self:GetCamLocked( cam ) ) then -- Get the heading of the player's vehicle and the hit vehicle local ownH = UTIL:Round( GetEntityHeading( PLY.veh ), 0 ) local tarH = UTIL:Round( GetEntityHeading( veh ), 0 ) @@ -233,16 +233,16 @@ function READER:Main() local dir = UTIL:GetEntityRelativeDirection( ownH, tarH ) -- Only run the rest of the plate check code if we can see the front or rear of the vehicle - if ( dir > 0 ) then - -- Get the licence plate text from the vehicle + if ( dir > 0 ) then + -- Get the licence plate text from the vehicle local plate = GetVehicleNumberPlateText( veh ) - -- Get the licence plate index from the vehicle + -- Get the licence plate index from the vehicle local index = GetVehicleNumberPlateTextIndex( veh ) -- Only update the stored plate if it's different, otherwise we'd keep sending a NUI message to update the displayed - -- plate and image even though they're the same - if ( self:GetPlate( cam ) ~= plate ) then + -- plate and image even though they're the same + if ( self:GetPlate( cam ) ~= plate ) then -- Set the plate for the current reader self:SetPlate( cam, plate ) @@ -250,24 +250,24 @@ function READER:Main() self:SetIndex( cam, index ) -- Automatically lock the plate if the scanned plate matches the BOLO - if ( plate == self:GetBoloPlate() ) then + if ( plate == self:GetBoloPlate() ) then self:LockCam( cam, false, true ) - end + end -- Send the plate information to the NUI side to update the UI SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) - -- If we use Sonoran CAD, reduce the plate events to just player's vehicle, otherwise life as normal - if ( ( CONFIG.use_sonorancad and ( UTIL:IsPlayerInVeh( veh ) or IsVehiclePreviouslyOwnedByPlayer( veh ) ) and GetVehicleClass( veh ) ~= 18 ) or not CONFIG.use_sonorancad ) then + -- If we use Sonoran CAD, reduce the plate events to just player's vehicle, otherwise life as normal + if ( ( CONFIG.use_sonorancad and ( UTIL:IsPlayerInVeh( veh ) or IsVehiclePreviouslyOwnedByPlayer( veh ) ) and GetVehicleClass( veh ) ~= 18 ) or not CONFIG.use_sonorancad ) then -- Trigger the event so developers can hook into the scanner every time a plate is scanned TriggerServerEvent( "wk:onPlateScanned", cam, plate, index ) - end - end - end - end - end - end -end + end + end + end + end + end + end +end -- Main thread Citizen.CreateThread( function() @@ -277,31 +277,31 @@ Citizen.CreateThread( function() -- Wait half a second Citizen.Wait( 500 ) - end + end end ) --- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not --- using it. Hides the radar UI when certain criteria is met, e.g. in pause menu or stepped out ot the --- patrol vehicle +-- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not +-- using it. Hides the radar UI when certain criteria is met, e.g. in pause menu or stepped out ot the +-- patrol vehicle function READER:RunDisplayValidationCheck() if ( ( ( PLY.veh == 0 or ( PLY.veh > 0 and not PLY.vehClassValid ) ) and self:GetDisplayState() and not self:GetDisplayHidden() ) or IsPauseMenuActive() and self:GetDisplayState() ) then - self:SetDisplayHidden( true ) + self:SetDisplayHidden( true ) SendNUIMessage( { _type = "setReaderDisplayState", state = false } ) elseif ( PLY:CanViewRadar() and self:GetDisplayState() and self:GetDisplayHidden() ) then - self:SetDisplayHidden( false ) + self:SetDisplayHidden( false ) SendNUIMessage( { _type = "setReaderDisplayState", state = true } ) - end + end end -- Runs the display validation check for the radar -Citizen.CreateThread( function() +Citizen.CreateThread( function() Citizen.Wait( 100 ) - while ( true ) do - -- Run the check + while ( true ) do + -- Run the check READER:RunDisplayValidationCheck() - -- Wait half a second + -- Wait half a second Citizen.Wait( 500 ) - end + end end ) \ No newline at end of file diff --git a/cl_player.lua b/cl_player.lua index de0fa53..29401b5 100644 --- a/cl_player.lua +++ b/cl_player.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -33,62 +33,62 @@ --[[---------------------------------------------------------------------------------- Player info variables ----------------------------------------------------------------------------------]]-- -PLY = +PLY = { ped = PlayerPedId(), veh = nil, inDriverSeat = false, - inPassengerSeat = false, + inPassengerSeat = false, vehClassValid = false } function PLY:VehicleStateValid() return DoesEntityExist( self.veh ) and self.veh > 0 and self.vehClassValid -end +end --- Used to check if the player is in a position where the radar should be allowed operation +-- Used to check if the player is in a position where the radar should be allowed operation function PLY:IsDriver() - return self:VehicleStateValid() and self.inDriverSeat -end + return self:VehicleStateValid() and self.inDriverSeat +end --- Returns if the player is in the front passenger seat of an emergency vehicle +-- Returns if the player is in the front passenger seat of an emergency vehicle function PLY:IsPassenger() - return self:VehicleStateValid() and self.inPassengerSeat -end + return self:VehicleStateValid() and self.inPassengerSeat +end --- Returns if the player can view the radar, ensures their vehicle state is valid and that they are a driver or +-- Returns if the player can view the radar, ensures their vehicle state is valid and that they are a driver or -- a passenger (where valid) function PLY:CanViewRadar() return self:IsDriver() or ( self:IsPassenger() and RADAR:IsPassengerViewAllowed() ) -end +end --- Returns if the player is allowed to control the radar from the passenger seat +-- Returns if the player is allowed to control the radar from the passenger seat function PLY:CanControlRadar() return self:IsDriver() or ( self:IsPassenger() and RADAR:IsPassengerControlAllowed() ) -end +end -- Returns the ped in the opposite seat to the player, e.g. if we're the passenger, then return the driver function PLY:GetOtherPed() - if ( self:IsDriver() ) then + if ( self:IsDriver() ) then return GetPedInVehicleSeat( PLY.veh, 0 ) elseif ( self:IsPassenger() ) then return GetPedInVehicleSeat( PLY.veh, -1 ) - end + end - return nil -end + return nil +end -- The main purpose of this thread is to update the information about the local player, including their -- ped id, the vehicle id (if they're in one), whether they're in a driver seat, and if the vehicle's class --- is valid or not +-- is valid or not Citizen.CreateThread( function() - while ( true ) do + while ( true ) do PLY.ped = PlayerPedId() PLY.veh = GetVehiclePedIsIn( PLY.ped, false ) - PLY.inDriverSeat = GetPedInVehicleSeat( PLY.veh, -1 ) == PLY.ped - PLY.inPassengerSeat = GetPedInVehicleSeat( PLY.veh, 0 ) == PLY.ped + PLY.inDriverSeat = GetPedInVehicleSeat( PLY.veh, -1 ) == PLY.ped + PLY.inPassengerSeat = GetPedInVehicleSeat( PLY.veh, 0 ) == PLY.ped PLY.vehClassValid = GetVehicleClass( PLY.veh ) == 18 Citizen.Wait( 500 ) - end + end end ) \ No newline at end of file diff --git a/cl_radar.lua b/cl_radar.lua index 8735760..bd7728e 100644 --- a/cl_radar.lua +++ b/cl_radar.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -30,21 +30,21 @@ ---------------------------------------------------------------------------------------]]-- --- Cache some of the main Lua functions and libraries -local next = next -local dot = dot -local table = table +-- Cache some of the main Lua functions and libraries +local next = next +local dot = dot +local table = table local type = type local tostring = tostring -local math = math -local pairs = pairs +local math = math +local pairs = pairs --[[---------------------------------------------------------------------------------- - Key bind registering + Key bind registering ----------------------------------------------------------------------------------]]-- local function RegisterKeyBinds() - if ( UTIL:IsResourceNameValid() ) then + if ( UTIL:IsResourceNameValid() ) then UTIL:Log( "Registering radar commands and key binds." ) -- Opens the remote control @@ -101,16 +101,16 @@ local function RegisterKeyBinds() UTIL:Log( "Radar data deleted, please immediately restart your game without opening the radar's remote." ) end, false ) - else + else UTIL:Log( "ERROR: Resource name is not wk_wars2x. Key binds will not be registered for compatibility reasons. Contact the server owner and ask them to change the resource name back to wk_wars2x" ) - end -end + end +end --[[---------------------------------------------------------------------------------- UI loading and key binds trigger ----------------------------------------------------------------------------------]]-- -local spawned = false +local spawned = false local function LoadUISettings() UTIL:Log( "Attempting to load saved UI settings data." ) @@ -119,40 +119,40 @@ local function LoadUISettings() local uiData = GetResourceKvpString( "wk_wars2x_ui_data" ) -- If the data exists, then we send it off! - if ( uiData ~= nil ) then + if ( uiData ~= nil ) then SendNUIMessage( { _type = "loadUiSettings", data = json.decode( uiData ) } ) - + UTIL:Log( "Saved UI settings data loaded!" ) -- If the data doesn't exist, then we send the defaults - else + else SendNUIMessage( { _type = "setUiDefaults", data = CONFIG.uiDefaults } ) UTIL:Log( "Could not find any saved UI settings data." ) - end -end + end +end -- Runs every time the player spawns, but the additional check means it only runs the first time -- the player spawns AddEventHandler( "playerSpawned", function() - if ( not spawned ) then + if ( not spawned ) then RegisterKeyBinds() LoadUISettings() spawned = true - end + end end ) --- Loads the UI settings when the resource gets restarted, this way active users don't have the +-- Loads the UI settings when the resource gets restarted, this way active users don't have the -- default settings applied AddEventHandler( "onResourceStart", function( resourceName ) - if ( GetCurrentResourceName() == resourceName ) then + if ( GetCurrentResourceName() == resourceName ) then Citizen.CreateThread( function() Citizen.Wait( 1000 ) RegisterKeyBinds() LoadUISettings() end ) - end + end end ) @@ -160,49 +160,49 @@ end ) Radar variables NOTE - This is not a config, do not touch anything unless you know what - you are actually doing. + you are actually doing. ----------------------------------------------------------------------------------]]-- RADAR = {} -RADAR.vars = +RADAR.vars = { - -- Whether or not the radar's UI is visible + -- Whether or not the radar's UI is visible displayed = false, - -- The radar's power, the system simulates the radar unit powering up when the user clicks the + -- The radar's power, the system simulates the radar unit powering up when the user clicks the -- power button on the interface - power = false, - poweringUp = false, + power = false, + poweringUp = false, -- Whether or not the radar should be hidden, e.g. the display is active but the player then steps -- out of their vehicle hidden = false, - -- These are the settings that are used in the operator menu + -- These are the settings that are used in the operator menu settings = { -- Should the system calculate and display faster targets - ["fastDisplay"] = CONFIG.menuDefaults["fastDisplay"], + ["fastDisplay"] = CONFIG.menuDefaults["fastDisplay"], -- Sensitivity for each radar mode, this changes how far the antennas will detect vehicles - ["same"] = CONFIG.menuDefaults["same"], - ["opp"] = CONFIG.menuDefaults["opp"], + ["same"] = CONFIG.menuDefaults["same"], + ["opp"] = CONFIG.menuDefaults["opp"], - -- The volume of the audible beep + -- The volume of the audible beep ["beep"] = CONFIG.menuDefaults["beep"], - - -- The volume of the verbal lock confirmation + + -- The volume of the verbal lock confirmation ["voice"] = CONFIG.menuDefaults["voice"], - - -- The volume of the plate reader audio - ["plateAudio"] = CONFIG.menuDefaults["plateAudio"], + + -- The volume of the plate reader audio + ["plateAudio"] = CONFIG.menuDefaults["plateAudio"], -- The speed unit used in conversions ["speedType"] = CONFIG.menuDefaults["speedType"] }, - -- These 3 variables are for the in-radar menu that can be accessed through the remote control, the menuOptions table - -- stores all of the information about each of the settings the user can change - menuActive = false, - currentOptionIndex = 1, + -- These 3 variables are for the in-radar menu that can be accessed through the remote control, the menuOptions table + -- stores all of the information about each of the settings the user can change + menuActive = false, + currentOptionIndex = 1, menuOptions = { { displayText = { "¦¦¦", "FAS" }, optionsText = { "On¦", "Off" }, options = { true, false }, optionIndex = -1, settingText = "fastDisplay" }, { displayText = { "¦SL", "SEn" }, optionsText = { "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "same" }, @@ -213,30 +213,30 @@ RADAR.vars = { displayText = { "Uni", "tS¦" }, optionsText = { "USA", "INT" }, options = { "mph", "kmh" }, optionIndex = -1, settingText = "speedType" } }, - -- Player's vehicle speed, mainly used in the dynamic thread wait update + -- Player's vehicle speed, mainly used in the dynamic thread wait update patrolSpeed = 0, - -- Antennas, this table contains all of the data needed for operation of the front and rear antennas + -- Antennas, this table contains all of the data needed for operation of the front and rear antennas antennas = { - -- Variables for the front antenna + -- Variables for the front antenna [ "front" ] = { - xmit = false, -- Whether the antenna is transmitting or in hold - mode = 0, -- Current antenna mode, 0 = none, 1 = same, 2 = opp, 3 = same and opp - speed = 0, -- Speed of the vehicle caught by the front antenna + xmit = false, -- Whether the antenna is transmitting or in hold + mode = 0, -- Current antenna mode, 0 = none, 1 = same, 2 = opp, 3 = same and opp + speed = 0, -- Speed of the vehicle caught by the front antenna dir = nil, -- Direction the caught vehicle is going, 0 = towards, 1 = away fastSpeed = 0, -- Speed of the fastest vehicle caught by the front antenna - fastDir = nil, -- Direction the fastest vehicle is going + fastDir = nil, -- Direction the fastest vehicle is going speedLocked = false, -- A speed has been locked for this antenna lockedSpeed = nil, -- The locked speed lockedDir = nil, -- The direction of the vehicle that was locked lockedType = nil -- The locked type, 1 = strongest, 2 = fastest - }, + }, -- Variables for the rear antenna [ "rear" ] = { xmit = false, -- Whether the antenna is transmitting or in hold - mode = 0, -- Current antenna mode, 0 = none, 1 = same, 2 = opp, 3 = same and opp - speed = 0, -- Speed of the vehicle caught by the front antenna + mode = 0, -- Current antenna mode, 0 = none, 1 = same, 2 = opp, 3 = same and opp + speed = 0, -- Speed of the vehicle caught by the front antenna dir = nil, -- Direction the caught vehicle is going, 0 = towards, 1 = away fastSpeed = 0, -- Speed of the fastest vehicle caught by the front antenna fastDir = nil, -- Direction the fastest vehicle is going @@ -245,16 +245,16 @@ RADAR.vars = lockedDir = nil, -- The direction of the vehicle that was locked lockedType = nil -- The locked type, 1 = strongest, 2 = fastest } - }, + }, -- The maximum distance that the radar system's ray traces can go, changing this will change the max -- distance in-game, but I wouldn't really put it more than 500.0 maxCheckDist = 350.0, - -- Cached dynamic vehicle sphere sizes, automatically populated when the system is running - sphereSizes = {}, + -- Cached dynamic vehicle sphere sizes, automatically populated when the system is running + sphereSizes = {}, - -- Table to store tables for hit entities of captured vehicles + -- Table to store tables for hit entities of captured vehicles capturedVehicles = {}, -- Table for temp id storage to stop unnecessary trace checks @@ -262,34 +262,34 @@ RADAR.vars = -- tempVehicleIDs = {}, -- Table to store the valid vehicle models - validVehicles = {}, + validVehicles = {}, - -- The current vehicle data for display + -- The current vehicle data for display activeVehicles = {}, -- Vehicle pool, automatically populated when the system is running, holds all of the current - -- vehicle IDs for the player using entity enumeration (see cl_utils.lua) - vehiclePool = {}, + -- vehicle IDs for the player using entity enumeration (see cl_utils.lua) + vehiclePool = {}, - -- Ray trace state, this is used so the radar system doesn't initiate another set of ray traces until - -- the current set has finished + -- Ray trace state, this is used so the radar system doesn't initiate another set of ray traces until + -- the current set has finished rayTraceState = 0, - -- Number of ray traces, automatically cached when the system first runs + -- Number of ray traces, automatically cached when the system first runs numberOfRays = 0, - -- The wait time for the ray trace system, this changes dynamically based on if the player's vehicle is stationary + -- The wait time for the ray trace system, this changes dynamically based on if the player's vehicle is stationary -- or not - threadWaitTime = 500, - - -- Key lock, when true, prevents any of the radar's key events from working, like the ELS key lock + threadWaitTime = 500, + + -- Key lock, when true, prevents any of the radar's key events from working, like the ELS key lock keyLock = false } -- Speed conversion values RADAR.speedConversions = { ["mph"] = 2.236936, ["kmh"] = 3.6 } --- These vectors are used in the custom ray tracing system +-- These vectors are used in the custom ray tracing system RADAR.rayTraces = { { startVec = { x = 0.0 }, endVec = { x = 0.0, y = 0.0 }, rayType = "same" }, { startVec = { x = -5.0 }, endVec = { x = -5.0, y = 0.0 }, rayType = "same" }, @@ -298,51 +298,51 @@ RADAR.rayTraces = { { startVec = { x = -17.0 }, endVec = { x = -17.0, y = 0.0 }, rayType = "opp" } } --- Each of these are used for sorting the captured vehicle data, the 'strongest' filter is used for the main +-- Each of these are used for sorting the captured vehicle data, the 'strongest' filter is used for the main -- target window of each antenna, whereas the 'fastest' filter is used for the fast target window of each antenna RADAR.sorting = { - strongest = function( a, b ) return a.size > b.size end, + strongest = function( a, b ) return a.size > b.size end, fastest = function( a, b ) return a.speed > b.speed end } --[[---------------------------------------------------------------------------------- - Radar essentials functions + Radar essentials functions ----------------------------------------------------------------------------------]]-- -- Returns if the radar's power is on or off function RADAR:IsPowerOn() - return self.vars.power -end + return self.vars.power +end -- Returns if the radar system is powering up, the powering up stage only takes 2 seconds function RADAR:IsPoweringUp() return self.vars.poweringUp -end +end --- Allows the powering up state variable to be set +-- Allows the powering up state variable to be set function RADAR:SetPoweringUpState( state ) - self.vars.poweringUp = state -end + self.vars.poweringUp = state +end -- Toggles the radar power function RADAR:TogglePower() - -- Only power up if the system is not already powering up - if ( not self:IsPoweringUp() ) then + -- Only power up if the system is not already powering up + if ( not self:IsPoweringUp() ) then -- Toggle the power variable - self.vars.power = not self.vars.power - - -- Send the NUI message to toggle the power + self.vars.power = not self.vars.power + + -- Send the NUI message to toggle the power SendNUIMessage( { _type = "radarPower", state = self:IsPowerOn() } ) - -- Power is now turned on - if ( self:IsPowerOn() ) then - -- Also make sure the operator menu is inactive + -- Power is now turned on + if ( self:IsPowerOn() ) then + -- Also make sure the operator menu is inactive self:SetMenuState( false ) - + -- Tell the system the radar is 'powering up' self:SetPoweringUpState( true ) - -- Set a 2 second countdown + -- Set a 2 second countdown Citizen.SetTimeout( 2000, function() -- Tell the system the radar has 'powered up' self:SetPoweringUpState( false ) @@ -350,44 +350,44 @@ function RADAR:TogglePower() -- Let the UI side know the system has loaded SendNUIMessage( { _type = "poweredUp" } ) end ) - else + else -- If the system is being turned off, then we reset the antennas self:ResetAntenna( "front" ) self:ResetAntenna( "rear" ) end - end + end end -- Toggles the display state of the radar system function RADAR:ToggleDisplayState() - -- Toggle the display variable - self.vars.displayed = not self.vars.displayed + -- Toggle the display variable + self.vars.displayed = not self.vars.displayed - -- Send the toggle message to the NUI side + -- Send the toggle message to the NUI side SendNUIMessage( { _type = "setRadarDisplayState", state = self:GetDisplayState() } ) -end +end -- Gets the display state function RADAR:GetDisplayState() return self.vars.displayed -end +end -- Used to set individual settings within RADAR.vars.settings, as all of the settings use string keys, using this -- function makes updating settings easier function RADAR:SetSettingValue( setting, value ) -- Make sure that we're not trying to set a nil value for the setting - if ( value ~= nil ) then - -- Set the setting's value - self.vars.settings[setting] = value + if ( value ~= nil ) then + -- Set the setting's value + self.vars.settings[setting] = value -- If the setting that's being updated is same or opp, then we update the end coordinates for the ray tracer - if ( setting == "same" or setting == "opp" ) then + if ( setting == "same" or setting == "opp" ) then self:UpdateRayEndCoords() - end - end -end + end + end +end --- Returns the value of the given setting +-- Returns the value of the given setting function RADAR:GetSettingValue( setting ) return self.vars.settings[setting] end @@ -395,78 +395,78 @@ end -- Return the state of the fastDisplay setting, short hand direct way to check if the fast system is enabled function RADAR:IsFastDisplayEnabled() return self.vars.settings["fastDisplay"] -end +end --- Returns if either of the antennas are transmitting +-- Returns if either of the antennas are transmitting function RADAR:IsEitherAntennaOn() return self:IsAntennaTransmitting( "front" ) or self:IsAntennaTransmitting( "rear" ) -end +end -- Sends an update to the NUI side with the current state of the antennas and if the fast system is enabled function RADAR:SendSettingUpdate() -- Create a table to store the setting information for the antennas local antennas = {} - -- Iterate through each antenna and grab the relevant information - for ant in UTIL:Values( { "front", "rear" } ) do + -- Iterate through each antenna and grab the relevant information + for ant in UTIL:Values( { "front", "rear" } ) do antennas[ant] = {} antennas[ant].xmit = self:IsAntennaTransmitting( ant ) antennas[ant].mode = self:GetAntennaMode( ant ) antennas[ant].speedLocked = self:IsAntennaSpeedLocked( ant ) antennas[ant].fast = self:ShouldFastBeDisplayed( ant ) - end + end -- Send a message to the NUI side with the current state of the antennas SendNUIMessage( { _type = "settingUpdate", antennaData = antennas } ) -end +end --- Returns if a main task can be performed --- A main task such as the ray trace thread should only run if the radar's power is on, the system is not in the --- process of powering up, and the operator menu is not open +-- Returns if a main task can be performed +-- A main task such as the ray trace thread should only run if the radar's power is on, the system is not in the +-- process of powering up, and the operator menu is not open function RADAR:CanPerformMainTask() return self:IsPowerOn() and not self:IsPoweringUp() and not self:IsMenuOpen() -end +end -- Returns what the dynamic thread wait time is function RADAR:GetThreadWaitTime() return self.vars.threadWaitTime -end +end --- Sets the dynamic thread wait time to the given value +-- Sets the dynamic thread wait time to the given value function RADAR:SetThreadWaitTime( time ) - self.vars.threadWaitTime = time -end + self.vars.threadWaitTime = time +end --- Sets the display's hidden state to the given state +-- Sets the display's hidden state to the given state function RADAR:SetDisplayHidden( state ) - self.vars.hidden = state -end + self.vars.hidden = state +end --- Returns if the display is hidden +-- Returns if the display is hidden function RADAR:GetDisplayHidden() - return self.vars.hidden + return self.vars.hidden end -- Opens the remote only if the pause menu is not open and the player's vehicle state is valid, as the --- passenger can also open the remote, we check the config variable as well. +-- passenger can also open the remote, we check the config variable as well. function RADAR:OpenRemote() - if ( not IsPauseMenuActive() and PLY:CanViewRadar() ) then + if ( not IsPauseMenuActive() and PLY:CanViewRadar() ) then -- Tell the NUI side to open the remote SendNUIMessage( { _type = "openRemote" } ) - if ( CONFIG.allow_quick_start_video ) then + if ( CONFIG.allow_quick_start_video ) then -- Display the new user popup if we can local show = GetResourceKvpInt( "wk_wars2x_new_user" ) - if ( show == 0 ) then + if ( show == 0 ) then SendNUIMessage( { _type = "showNewUser" } ) - end - end + end + end - -- Bring focus to the NUI side + -- Bring focus to the NUI side SetNuiFocus( true, true ) end -end +end -- Event to open the remote RegisterNetEvent( "wk:openRemote" ) @@ -474,21 +474,21 @@ AddEventHandler( "wk:openRemote", function() RADAR:OpenRemote() end ) --- Returns if the passenger can view the radar too +-- Returns if the passenger can view the radar too function RADAR:IsPassengerViewAllowed() return CONFIG.allow_passenger_view -end +end --- Returns if the passenger can control the radar and plate reader, reliant on the passenger being --- able to view the radar and plate reader too +-- Returns if the passenger can control the radar and plate reader, reliant on the passenger being +-- able to view the radar and plate reader too function RADAR:IsPassengerControlAllowed() return CONFIG.allow_passenger_view and CONFIG.allow_passenger_control -end +end -- Returns if we only auto lock vehicle speeds if said vehicle is a player function RADAR:OnlyLockFastPlayers() return CONFIG.only_lock_players -end +end -- Returns if the fast limit option should be available for the radar function RADAR:IsFastLimitAllowed() @@ -497,256 +497,256 @@ end -- Only create the functions if the fast limit config option is enabled if ( RADAR:IsFastLimitAllowed() ) then - -- Adds settings into the radar's variables for when the allow_fast_limit variable is true + -- Adds settings into the radar's variables for when the allow_fast_limit variable is true function RADAR:CreateFastLimitConfig() - -- Create the options for the menu - local fastOptions = + -- Create the options for the menu + local fastOptions = { { displayText = { "FAS", "Loc" }, optionsText = { "On¦", "Off" }, options = { true, false }, optionIndex = 2, settingText = "fastLock" }, { displayText = { "FAS", "SPd" }, optionsText = {}, options = {}, optionIndex = 12, settingText = "fastLimit" } } - -- Iterate from 5 to 200 in steps of 5 and insert into the fast limit option + -- Iterate from 5 to 200 in steps of 5 and insert into the fast limit option for i = 5, 200, 5 do local text = UTIL:FormatSpeed( i ) table.insert( fastOptions[2].optionsText, text ) table.insert( fastOptions[2].options, i ) - end + end - -- Create the settings with the default options + -- Create the settings with the default options self:SetSettingValue( "fastLock", false ) self:SetSettingValue( "fastLimit", 60 ) - -- Add the fast options to the main menu options table + -- Add the fast options to the main menu options table table.insert( self.vars.menuOptions, fastOptions[1] ) table.insert( self.vars.menuOptions, fastOptions[2] ) - end + end - -- Returns the numerical fast limit + -- Returns the numerical fast limit function RADAR:GetFastLimit() return self.vars.settings["fastLimit"] - end + end -- Returns if the fast lock menu option is on or off function RADAR:IsFastLockEnabled() return self.vars.settings["fastLock"] - end -end + end +end -- Toggles the internal key lock state, which stops any of the radar's key binds from working function RADAR:ToggleKeyLock() -- Check the player state is valid - if ( PLY:CanViewRadar() ) then - -- Toggle the key lock variable + if ( PLY:CanViewRadar() ) then + -- Toggle the key lock variable self.vars.keyLock = not self.vars.keyLock -- Tell the NUI side to display the key lock message SendNUIMessage( { _type = "displayKeyLock", state = self:GetKeyLockState() } ) end -end +end --- Returns the key lock state +-- Returns the key lock state function RADAR:GetKeyLockState() return self.vars.keyLock -end +end --[[---------------------------------------------------------------------------------- - Radar menu functions + Radar menu functions ----------------------------------------------------------------------------------]]-- -- Sets the menu state to the given state function RADAR:SetMenuState( state ) - -- Make sure that the radar's power is on - if ( self:IsPowerOn() ) then - -- Set the menuActive variable to the given state + -- Make sure that the radar's power is on + if ( self:IsPowerOn() ) then + -- Set the menuActive variable to the given state self.vars.menuActive = state -- If we are opening the menu, make sure the first item is displayed - if ( state ) then + if ( state ) then self.vars.currentOptionIndex = 1 end end -end +end --- Returns if the operator menu is open +-- Returns if the operator menu is open function RADAR:IsMenuOpen() return self.vars.menuActive -end +end --- This function changes the menu index variable so the user can iterate through the options in the operator menu +-- This function changes the menu index variable so the user can iterate through the options in the operator menu function RADAR:ChangeMenuIndex() -- Create a temporary variable of the current menu index plus 1 local temp = self.vars.currentOptionIndex + 1 -- If the temporary value is larger than how many options there are, set it to 1, this way the menu - -- loops back round to the start of the menu - if ( temp > #self.vars.menuOptions ) then - temp = 1 - end + -- loops back round to the start of the menu + if ( temp > #self.vars.menuOptions ) then + temp = 1 + end -- Set the menu index variable to the temporary value we created self.vars.currentOptionIndex = temp -- Call the function to send an update to the NUI side self:SendMenuUpdate() -end +end -- Returns the option table of the current menu index function RADAR:GetMenuOptionTable() return self.vars.menuOptions[self.vars.currentOptionIndex] -end +end --- Changes the index for an individual option +-- Changes the index for an individual option -- E.g. { "On" "Off" }, index = 2 would be "Off" function RADAR:SetMenuOptionIndex( index ) self.vars.menuOptions[self.vars.currentOptionIndex].optionIndex = index -end +end --- Returns the option value for the current option +-- Returns the option value for the current option function RADAR:GetMenuOptionValue() local opt = self:GetMenuOptionTable() local index = opt.optionIndex return opt.options[index] -end +end -- This function is similar to RADAR:ChangeMenuIndex() but allows for iterating forward and backward through options function RADAR:ChangeMenuOption( dir ) - -- Get the option table of the currently selected option + -- Get the option table of the currently selected option local opt = self:GetMenuOptionTable() - -- Get the current option index of the selected option + -- Get the current option index of the selected option local index = opt.optionIndex - -- Cache the size of this setting's options table + -- Cache the size of this setting's options table local size = #opt.options -- As the XMIT/HOLD buttons are used for changing the option values, we have to check which button is being pressed - if ( dir == "front" ) then + if ( dir == "front" ) then index = index + 1 - if ( index > size ) then index = 1 end - elseif ( dir == "rear" ) then + if ( index > size ) then index = 1 end + elseif ( dir == "rear" ) then index = index - 1 - if ( index < 1 ) then index = size end + if ( index < 1 ) then index = size end end - -- Update the option's index + -- Update the option's index self:SetMenuOptionIndex( index ) - -- Change the value of the setting in the main RADAR.vars.settings table + -- Change the value of the setting in the main RADAR.vars.settings table self:SetSettingValue( opt.settingText, self:GetMenuOptionValue() ) -- Call the function to send an update to the NUI side self:SendMenuUpdate() -end +end -- Returns what text should be displayed in the boxes for the current option -- E.g. "¦SL" "SEN" function RADAR:GetMenuOptionDisplayText() return self:GetMenuOptionTable().displayText -end +end --- Returns the option text of the currently selected setting +-- Returns the option text of the currently selected setting function RADAR:GetMenuOptionText() local opt = self:GetMenuOptionTable() return opt.optionsText[opt.optionIndex] -end +end --- Sends a message to the NUI side with updated information on what should be displayed for the menu +-- Sends a message to the NUI side with updated information on what should be displayed for the menu function RADAR:SendMenuUpdate() SendNUIMessage( { _type = "menu", text = self:GetMenuOptionDisplayText(), option = self:GetMenuOptionText() } ) -end +end --- Attempts to load the saved operator menu data +-- Attempts to load the saved operator menu data function RADAR:LoadOMData() UTIL:Log( "Attempting to load saved operator menu data." ) -- Try and get the data local rawData = GetResourceKvpString( "wk_wars2x_om_data" ) - -- If the data exists, decode it and replace the operator menu table - if ( rawData ~= nil ) then + -- If the data exists, decode it and replace the operator menu table + if ( rawData ~= nil ) then local omData = json.decode( rawData ) self.vars.settings = omData UTIL:Log( "Saved operator menu data loaded!" ) - else + else UTIL:Log( "Could not find any saved operator menu data." ) - end -end + end +end --- Updates the operator menu option indexes, as the default menu values can be changed in the config, we +-- Updates the operator menu option indexes, as the default menu values can be changed in the config, we -- need to update the indexes otherwise the menu will display the wrong values function RADAR:UpdateOptionIndexes() self:LoadOMData() -- Iterate through each of the internal settings - for k, v in pairs( self.vars.settings ) do + for k, v in pairs( self.vars.settings ) do -- Iterate through all of the menu options - for i, t in pairs( self.vars.menuOptions ) do + for i, t in pairs( self.vars.menuOptions ) do -- If the current menu option is the same as the current setting - if ( t.settingText == k ) then - -- Iterate through the option values of the current menu option - for oi, ov in pairs( t.options ) do + if ( t.settingText == k ) then + -- Iterate through the option values of the current menu option + for oi, ov in pairs( t.options ) do -- If the value of the current option set in the config matches the current value of -- the option value, then we update the option index variable - if ( v == ov ) then + if ( v == ov ) then t.optionIndex = oi - end - end - end - end - end -end + end + end + end + end + end +end --[[---------------------------------------------------------------------------------- - Radar basics functions + Radar basics functions ----------------------------------------------------------------------------------]]-- -- Returns the patrol speed value stored -function RADAR:GetPatrolSpeed() +function RADAR:GetPatrolSpeed() return self.vars.patrolSpeed -end +end --- Returns the current vehicle pool +-- Returns the current vehicle pool function RADAR:GetVehiclePool() return self.vars.vehiclePool -end +end --- Returns the maximum distance a ray trace can go +-- Returns the maximum distance a ray trace can go function RADAR:GetMaxCheckDist() return self.vars.maxCheckDist -end +end -- Returns the table sorting function 'strongest' function RADAR:GetStrongestSortFunc() - return self.sorting.strongest -end + return self.sorting.strongest +end -- Returns the table sorting function 'fastest' function RADAR:GetFastestSortFunc() return self.sorting.fastest -end +end --- Sets the patrol speed to a formatted version of the given number +-- Sets the patrol speed to a formatted version of the given number function RADAR:SetPatrolSpeed( speed ) - if ( type( speed ) == "number" ) then + if ( type( speed ) == "number" ) then self.vars.patrolSpeed = self:GetVehSpeedConverted( speed ) end end -- Sets the vehicle pool to the given value if it's a table function RADAR:SetVehiclePool( pool ) - if ( type( pool ) == "table" ) then - self.vars.vehiclePool = pool + if ( type( pool ) == "table" ) then + self.vars.vehiclePool = pool end -end +end --[[---------------------------------------------------------------------------------- - Radar ray trace functions + Radar ray trace functions ----------------------------------------------------------------------------------]]-- -- Returns what the current ray trace state is function RADAR:GetRayTraceState() @@ -756,7 +756,7 @@ end -- Caches the number of ray traces in RADAR.rayTraces function RADAR:CacheNumRays() self.vars.numberOfRays = #self.rayTraces -end +end -- Returns the number of ray traces the system has function RADAR:GetNumOfRays() @@ -766,69 +766,69 @@ end -- Increases the system's ray trace state ny 1 function RADAR:IncreaseRayTraceState() self.vars.rayTraceState = self.vars.rayTraceState + 1 -end +end -- Resets the ray trace state to 0 function RADAR:ResetRayTraceState() self.vars.rayTraceState = 0 -end +end --- This function is used to determine if a sphere intersect is in front or behind the player's vehicle, the --- sphere intersect calculation has a 'tProj' value that is a line from the centre of the sphere that goes onto --- the line being traced. This value will either be positive or negative and can be used to work out the +-- This function is used to determine if a sphere intersect is in front or behind the player's vehicle, the +-- sphere intersect calculation has a 'tProj' value that is a line from the centre of the sphere that goes onto +-- the line being traced. This value will either be positive or negative and can be used to work out the -- relative position of a point. function RADAR:GetIntersectedVehIsFrontOrRear( t ) - if ( t > 8.0 ) then - return 1 -- vehicle is in front - elseif ( t < -8.0 ) then + if ( t > 8.0 ) then + return 1 -- vehicle is in front + elseif ( t < -8.0 ) then return -1 -- vehicle is behind - end + end return 0 -- vehicle is next to self -end +end -- This function is used to check if a line going from point A to B intersects with a given sphere, it's used in -- the radar system to check if the patrol vehicle can detect any vehicles. As the default ray trace system in GTA -- cannot detect vehicles beyond 40~ units, my system acts as a replacement that allows the detection of vehicles -- much further away (400+ units). Also, as my system uses sphere intersections, each sphere can have a different --- radius, which means that larger vehicles can have larger spheres, and smaller vehicles can have smaller spheres. +-- radius, which means that larger vehicles can have larger spheres, and smaller vehicles can have smaller spheres. function RADAR:GetLineHitsSphereAndDir( c, radius, rs, re ) - -- Take the vector3's and turn them into vector2's, this way all of the calculations below are for an + -- Take the vector3's and turn them into vector2's, this way all of the calculations below are for an -- infinite cylinder rather than a sphere, which also means that vehicles can be detected even when on - -- an incline! + -- an incline! local rayStart = vector2( rs.x, rs.y ) local rayEnd = vector2( re.x, re.y ) local centre = vector2( c.x, c.y ) - -- First we get the normalised ray, this way we then know the direction the ray is going + -- First we get the normalised ray, this way we then know the direction the ray is going local rayNorm = norm( rayEnd - rayStart ) -- Then we calculate the ray from the start point to the centre position of the sphere local rayToCentre = centre - rayStart - -- Now that we have the ray to the centre of the sphere, and the normalised ray direction, we - -- can calculate the shortest point from the centre of the sphere onto the ray itself. This - -- would then give us the opposite side of the right angled triangle. All of the resulting - -- values are also in squared form, as performing square root functions is slower. + -- Now that we have the ray to the centre of the sphere, and the normalised ray direction, we + -- can calculate the shortest point from the centre of the sphere onto the ray itself. This + -- would then give us the opposite side of the right angled triangle. All of the resulting + -- values are also in squared form, as performing square root functions is slower. local tProj = dot( rayToCentre, rayNorm ) local oppLenSqr = dot( rayToCentre, rayToCentre ) - ( tProj * tProj ) -- Square the radius - local radiusSqr = radius * radius + local radiusSqr = radius * radius -- Calculate the distance of the ray trace to make sure we only return valid results if the trace -- is actually within the distance local rayDist = #( rayEnd - rayStart ) local distToCentre = #( rayStart - centre ) - ( radius * 2 ) - -- Now all we have to do is compare the squared opposite length and the radius squared, this + -- Now all we have to do is compare the squared opposite length and the radius squared, this -- will then tell us if the ray intersects with the sphere. - if ( oppLenSqr < radiusSqr and not ( distToCentre > rayDist ) ) then + if ( oppLenSqr < radiusSqr and not ( distToCentre > rayDist ) ) then return true, self:GetIntersectedVehIsFrontOrRear( tProj ) end - return false, nil -end + return false, nil +end -- This function is used to check if the target vehicle is in the same general traffic flow as the player's vehicle -- is sitting. If the angle is too great, then the radar would have an incorrect return for the speed. @@ -851,30 +851,30 @@ end -- This function is the main custom ray trace function, it performs most of the major tasks for checking a vehicle -- is valid and should be tested. It also makes use of the LOS native to make sure that we can only trace a vehicle -- if actually nas a direct line of sight with the player's vehicle, this way we don't pick up vehicles behind walls --- for example. It then creates a dynamic sphere for the vehicle based on the actual model dimensions of it, adds a --- small bit of realism, as real radars usually return the strongest target speed. +-- for example. It then creates a dynamic sphere for the vehicle based on the actual model dimensions of it, adds a +-- small bit of realism, as real radars usually return the strongest target speed. function RADAR:ShootCustomRay( plyVeh, veh, s, e ) -- Get the world coordinates of the target vehicle local pos = GetEntityCoords( veh ) - -- Calculate the distance between the target vehicle and the start point of the ray trace, note how we don't - -- use GetDistanceBetweenCoords or Vdist, the method below still returns the same result with less cpu time + -- Calculate the distance between the target vehicle and the start point of the ray trace, note how we don't + -- use GetDistanceBetweenCoords or Vdist, the method below still returns the same result with less cpu time local dist = #( pos - s ) - -- We only perform a trace on the target vehicle if it exists, isn't the player's vehicle, and the distance is - -- less than the max distance defined by the system - if ( DoesEntityExist( veh ) and veh ~= plyVeh and dist < self:GetMaxCheckDist() ) then - -- Get the speed of the target vehicle + -- We only perform a trace on the target vehicle if it exists, isn't the player's vehicle, and the distance is + -- less than the max distance defined by the system + if ( DoesEntityExist( veh ) and veh ~= plyVeh and dist < self:GetMaxCheckDist() ) then + -- Get the speed of the target vehicle local entSpeed = GetEntitySpeed( veh ) - -- Check that the target vehicle is within the line of sight of the player's vehicle + -- Check that the target vehicle is within the line of sight of the player's vehicle local visible = HasEntityClearLosToEntity( plyVeh, veh, 15 ) -- 13 seems okay, 15 too (doesn't grab ents through ents) - + -- Get the pitch of the player's vehicle local pitch = GetEntityPitch( plyVeh ) - -- Now we check that the target vehicle is moving and is visible - if ( entSpeed > 0.1 and ( pitch > -35 and pitch < 35 ) and visible ) then + -- Now we check that the target vehicle is moving and is visible + if ( entSpeed > 0.1 and ( pitch > -35 and pitch < 35 ) and visible ) then -- Get the dynamic radius as well as the size of the target vehicle local radius, size = self:GetDynamicRadius( veh ) @@ -882,55 +882,55 @@ function RADAR:ShootCustomRay( plyVeh, veh, s, e ) local hit, relPos = self:GetLineHitsSphereAndDir( pos, radius, s, e ) -- Return all of the information if the vehicle was hit and is in the flow of traffic - if ( hit and self:IsVehicleInTraffic( veh, relPos ) ) then + if ( hit and self:IsVehicleInTraffic( veh, relPos ) ) then return true, relPos, dist, entSpeed, size - end + end end - end + end -- Return a whole lot of nothing return false, nil, nil, nil, nil -end +end --- This function is used to gather all of the data on vehicles that have been hit by the given trace line, when --- a vehicle is hit, all of the information about that vehicle is put into a keyless table which is then inserted --- into a main table. When the loop has finished, the function then returns the table with all of the data. +-- This function is used to gather all of the data on vehicles that have been hit by the given trace line, when +-- a vehicle is hit, all of the information about that vehicle is put into a keyless table which is then inserted +-- into a main table. When the loop has finished, the function then returns the table with all of the data. function RADAR:GetVehsHitByRay( ownVeh, vehs, s, e ) -- Create the table that will be used to store all of the results local caughtVehs = {} -- Set the variable to say if there has been data collected - local hasData = false + local hasData = false -- Iterate through all of the vehicles - for _, veh in pairs( vehs ) do + for _, veh in pairs( vehs ) do -- Shoot a custom ray trace to see if the vehicle gets hit local hit, relativePos, distance, speed, size = self:ShootCustomRay( ownVeh, veh, s, e ) - -- If the vehicle is hit, then we create a table containing all of the information - if ( hit ) then + -- If the vehicle is hit, then we create a table containing all of the information + if ( hit ) then -- Create the table to store the data local vehData = {} - vehData.veh = veh + vehData.veh = veh vehData.relPos = relativePos vehData.dist = distance vehData.speed = speed vehData.size = size - -- Insert the table into the caught vehicles table + -- Insert the table into the caught vehicles table table.insert( caughtVehs, vehData ) -- Change the has data variable to true, this way the table will be returned - hasData = true - end - end + hasData = true + end + end -- If the caughtVehs table actually has data, then return it if ( hasData ) then return caughtVehs end -end +end --- This function is used to gather all of the vehicles hit by a given line trace, and then insert it into the --- internal captured vehicles table. +-- This function is used to gather all of the vehicles hit by a given line trace, and then insert it into the +-- internal captured vehicles table. function RADAR:CreateRayThread( vehs, from, startX, endX, endY, rayType ) -- Get the start and end points for the ray trace based on the given start and end coordinates local startPoint = GetOffsetFromEntityInWorldCoords( from, startX, 0.0, 0.0 ) @@ -939,107 +939,107 @@ function RADAR:CreateRayThread( vehs, from, startX, endX, endY, rayType ) -- Get all of the vehicles hit by the ray local hitVehs = self:GetVehsHitByRay( from, vehs, startPoint, endPoint ) - -- Insert the captured vehicle data and pass the ray type too + -- Insert the captured vehicle data and pass the ray type too self:InsertCapturedVehicleData( hitVehs, rayType ) - -- Increase the ray trace state + -- Increase the ray trace state self:IncreaseRayTraceState() -end +end --- This function iterates through each of the traces defined in RADAR.rayTraces and creates a 'thread' for +-- This function iterates through each of the traces defined in RADAR.rayTraces and creates a 'thread' for -- them, passing along all of the vehicle pool data and the player's vehicle function RADAR:CreateRayThreads( ownVeh, vehicles ) - for _, v in pairs( self.rayTraces ) do + for _, v in pairs( self.rayTraces ) do self:CreateRayThread( vehicles, ownVeh, v.startVec.x, v.endVec.x, v.endVec.y, v.rayType ) - end -end + end +end -- When the user changes either the same lane or opp lane sensitivity from within the operator menu, this function -- is then called to update the end coordinates for all of the traces function RADAR:UpdateRayEndCoords() - for _, v in pairs( self.rayTraces ) do + for _, v in pairs( self.rayTraces ) do -- Calculate what the new end coordinate should be local endY = self:GetSettingValue( v.rayType ) * self:GetMaxCheckDist() - - -- Update the end Y coordinate in the traces table + + -- Update the end Y coordinate in the traces table v.endVec.y = endY - end -end + end +end --[[---------------------------------------------------------------------------------- - Radar antenna functions + Radar antenna functions ----------------------------------------------------------------------------------]]-- --- Toggles the state of the given antenna between hold and transmitting, only works if the radar's power is +-- Toggles the state of the given antenna between hold and transmitting, only works if the radar's power is -- on. Also runs a callback function when present. function RADAR:ToggleAntenna( ant, cb ) - -- Check power is on - if ( self:IsPowerOn() ) then + -- Check power is on + if ( self:IsPowerOn() ) then -- Toggle the given antennas state - self.vars.antennas[ant].xmit = not self.vars.antennas[ant].xmit + self.vars.antennas[ant].xmit = not self.vars.antennas[ant].xmit - -- Run the callback function if there is one - if ( cb ) then cb() end - end -end + -- Run the callback function if there is one + if ( cb ) then cb() end + end +end -- Returns if the given antenna is transmitting function RADAR:IsAntennaTransmitting( ant ) - return self.vars.antennas[ant].xmit -end + return self.vars.antennas[ant].xmit +end -- Returns if the given relative position value is for the front or rear antenna function RADAR:GetAntennaTextFromNum( relPos ) - if ( relPos == 1 ) then + if ( relPos == 1 ) then return "front" - elseif ( relPos == -1 ) then + elseif ( relPos == -1 ) then return "rear" - end -end + end +end -- Returns the mode of the given antenna function RADAR:GetAntennaMode( ant ) - return self.vars.antennas[ant].mode -end + return self.vars.antennas[ant].mode +end --- Sets the mode of the given antenna if the mode is valid and the power is on. Also runs a callback function +-- Sets the mode of the given antenna if the mode is valid and the power is on. Also runs a callback function -- when present. function RADAR:SetAntennaMode( ant, mode, cb ) - -- Check the mode is actually a number, this is needed as the radar system relies on the mode to be - -- a number to work - if ( type( mode ) == "number" ) then + -- Check the mode is actually a number, this is needed as the radar system relies on the mode to be + -- a number to work + if ( type( mode ) == "number" ) then -- Check the mode is in the valid range for modes, and that the power is on - if ( mode >= 0 and mode <= 3 and self:IsPowerOn() ) then + if ( mode >= 0 and mode <= 3 and self:IsPowerOn() ) then -- Update the mode for the antenna - self.vars.antennas[ant].mode = mode + self.vars.antennas[ant].mode = mode - -- Run the callback function if there is one - if ( cb ) then cb() end - end - end -end + -- Run the callback function if there is one + if ( cb ) then cb() end + end + end +end -- Returns the speed stored for the given antenna function RADAR:GetAntennaSpeed( ant ) - return self.vars.antennas[ant].speed -end + return self.vars.antennas[ant].speed +end -- Sets the speed of the given antenna to the given speed -function RADAR:SetAntennaSpeed( ant, speed ) +function RADAR:SetAntennaSpeed( ant, speed ) self.vars.antennas[ant].speed = speed -end +end -- Returns the direction value stored for the given antenna function RADAR:GetAntennaDir( ant ) - return self.vars.antennas[ant].dir -end + return self.vars.antennas[ant].dir +end --- Sets the direction value of the given antenna to the given direction +-- Sets the direction value of the given antenna to the given direction function RADAR:SetAntennaDir( ant, dir ) - self.vars.antennas[ant].dir = dir -end + self.vars.antennas[ant].dir = dir +end --- Sets the fast speed and direction in one go +-- Sets the fast speed and direction in one go function RADAR:SetAntennaData( ant, speed, dir ) self:SetAntennaSpeed( ant, speed ) self:SetAntennaDir( ant, dir ) @@ -1047,25 +1047,25 @@ end -- Returns the fast speed stored for the given antenna function RADAR:GetAntennaFastSpeed( ant ) - return self.vars.antennas[ant].fastSpeed -end + return self.vars.antennas[ant].fastSpeed +end -- Sets the fast speed of the given antenna to the given speed -function RADAR:SetAntennaFastSpeed( ant, speed ) +function RADAR:SetAntennaFastSpeed( ant, speed ) self.vars.antennas[ant].fastSpeed = speed -end +end -- Returns the direction value for the fast box stored for the given antenna function RADAR:GetAntennaFastDir( ant ) return self.vars.antennas[ant].fastDir -end +end --- Sets the direction value of the given antenna's fast box to the given direction +-- Sets the direction value of the given antenna's fast box to the given direction function RADAR:SetAntennaFastDir( ant, dir ) - self.vars.antennas[ant].fastDir = dir -end + self.vars.antennas[ant].fastDir = dir +end --- Sets the fast speed and direction in one go +-- Sets the fast speed and direction in one go function RADAR:SetAntennaFastData( ant, speed, dir ) self:SetAntennaFastSpeed( ant, speed ) self:SetAntennaFastDir( ant, dir ) @@ -1073,148 +1073,148 @@ end -- Returns if the stored speed for the given antenna is valid function RADAR:DoesAntennaHaveValidData( ant ) - return self:GetAntennaSpeed( ant ) ~= nil -end + return self:GetAntennaSpeed( ant ) ~= nil +end -- Returns if the stored fast speed for the given antenna is valid function RADAR:DoesAntennaHaveValidFastData( ant ) - return self:GetAntennaFastSpeed( ant ) ~= nil -end + return self:GetAntennaFastSpeed( ant ) ~= nil +end --- Returns if the fast label should be displayed +-- Returns if the fast label should be displayed function RADAR:ShouldFastBeDisplayed( ant ) - if ( self:IsAntennaSpeedLocked( ant ) ) then - return self:GetAntennaLockedType( ant ) == 2 - else + if ( self:IsAntennaSpeedLocked( ant ) ) then + return self:GetAntennaLockedType( ant ) == 2 + else return self:IsFastDisplayEnabled() end -end +end -- Returns if the given antenna has a locked speed function RADAR:IsAntennaSpeedLocked( ant ) return self.vars.antennas[ant].speedLocked end --- Sets the state of speed lock for the given antenna to the given state +-- Sets the state of speed lock for the given antenna to the given state function RADAR:SetAntennaSpeedIsLocked( ant, state ) self.vars.antennas[ant].speedLocked = state -end +end --- Sets a speed and direction to be locked in for the given antenna +-- Sets a speed and direction to be locked in for the given antenna function RADAR:SetAntennaSpeedLock( ant, speed, dir, lockType ) -- Check that the passed speed and direction are actually valid - if ( speed ~= nil and dir ~= nil and lockType ~= nil ) then + if ( speed ~= nil and dir ~= nil and lockType ~= nil ) then -- Set the locked speed and direction to the passed values - self.vars.antennas[ant].lockedSpeed = speed - self.vars.antennas[ant].lockedDir = dir + self.vars.antennas[ant].lockedSpeed = speed + self.vars.antennas[ant].lockedDir = dir self.vars.antennas[ant].lockedType = lockType - + -- Tell the system that a speed has been locked for the given antenna self:SetAntennaSpeedIsLocked( ant, true ) -- Send a message to the NUI side to play the beep sound with the current volume setting SendNUIMessage( { _type = "audio", name = "beep", vol = self:GetSettingValue( "beep" ) } ) - - -- Send a message to the NUI side to play the lock audio with the current voice volume setting + + -- Send a message to the NUI side to play the lock audio with the current voice volume setting SendNUIMessage( { _type = "lockAudio", ant = ant, dir = dir, vol = self:GetSettingValue( "voice" ) } ) - + -- Great Scott! - if ( speed == "¦88" and self:GetSettingValue( "speedType" ) == "mph" ) then + if ( speed == "¦88" and self:GetSettingValue( "speedType" ) == "mph" ) then math.randomseed( GetGameTimer() ) local chance = math.random() - + -- 15% chance - if ( chance <= 0.15 ) then + if ( chance <= 0.15 ) then SendNUIMessage( { _type = "audio", name = "speed_alert", vol = self:GetSettingValue( "beep" ) } ) - end - end + end + end end -end +end -- Returns the locked speed for the given antenna function RADAR:GetAntennaLockedSpeed( ant ) return self.vars.antennas[ant].lockedSpeed -end +end -- Returns the locked direction for the given antenna function RADAR:GetAntennaLockedDir( ant ) return self.vars.antennas[ant].lockedDir -end +end -- Returns the lock type for the given antenna function RADAR:GetAntennaLockedType( ant ) - return self.vars.antennas[ant].lockedType -end + return self.vars.antennas[ant].lockedType +end -- Resets the speed lock info to do with the given antenna function RADAR:ResetAntennaSpeedLock( ant ) -- Blank the locked speed and direction - self.vars.antennas[ant].lockedSpeed = nil - self.vars.antennas[ant].lockedDir = nil + self.vars.antennas[ant].lockedSpeed = nil + self.vars.antennas[ant].lockedDir = nil self.vars.antennas[ant].lockedType = nil - + -- Set the locked state to false self:SetAntennaSpeedIsLocked( ant, false ) end --- When the user presses the speed lock key for either antenna, this function is called to get the +-- When the user presses the speed lock key for either antenna, this function is called to get the -- necessary information from the antenna, and then lock it into the display function RADAR:LockAntennaSpeed( ant ) -- Only lock a speed if the antenna is on and the UI is displayed - if ( self:IsPowerOn() and self:GetDisplayState() and not self:GetDisplayHidden() and self:IsAntennaTransmitting( ant ) ) then - -- Check if the antenna doesn't have a locked speed, if it doesn't then we lock in the speed, otherwise we - -- reset the lock - if ( not self:IsAntennaSpeedLocked( ant ) ) then + if ( self:IsPowerOn() and self:GetDisplayState() and not self:GetDisplayHidden() and self:IsAntennaTransmitting( ant ) ) then + -- Check if the antenna doesn't have a locked speed, if it doesn't then we lock in the speed, otherwise we + -- reset the lock + if ( not self:IsAntennaSpeedLocked( ant ) ) then -- Set up a temporary table with 3 nil values, this way if the system isn't able to get a speed or - -- direction, the speed lock function won't work + -- direction, the speed lock function won't work local data = { nil, nil, nil } - -- As the lock system is based on which speed is displayed, we have to check if there is a speed in the + -- As the lock system is based on which speed is displayed, we have to check if there is a speed in the -- fast box, if there is then we lock in the fast speed, otherwise we lock in the strongest speed - if ( self:IsFastDisplayEnabled() and self:DoesAntennaHaveValidFastData( ant ) ) then - data[1] = self:GetAntennaFastSpeed( ant ) - data[2] = self:GetAntennaFastDir( ant ) + if ( self:IsFastDisplayEnabled() and self:DoesAntennaHaveValidFastData( ant ) ) then + data[1] = self:GetAntennaFastSpeed( ant ) + data[2] = self:GetAntennaFastDir( ant ) data[3] = 2 - else - data[1] = self:GetAntennaSpeed( ant ) - data[2] = self:GetAntennaDir( ant ) + else + data[1] = self:GetAntennaSpeed( ant ) + data[2] = self:GetAntennaDir( ant ) data[3] = 1 end -- Lock in the speed data for the antenna self:SetAntennaSpeedLock( ant, data[1], data[2], data[3] ) - else + else self:ResetAntennaSpeedLock( ant ) - end + end -- Send an NUI message to change the lock label, otherwise we'd have to wait until the next main loop SendNUIMessage( { _type = "antennaLock", ant = ant, state = self:IsAntennaSpeedLocked( ant ) } ) SendNUIMessage( { _type = "antennaFast", ant = ant, state = self:ShouldFastBeDisplayed( ant ) } ) - end -end + end +end -- Resets an antenna, used when the system is turned off function RADAR:ResetAntenna( ant ) -- Overwrite default behaviour, this is because when the system is turned off, the temporary memory is - -- technically reset, as the setter functions require either the radar power to be on or the antenna to + -- technically reset, as the setter functions require either the radar power to be on or the antenna to -- be transmitting, this is the only way to reset the values - self.vars.antennas[ant].xmit = false + self.vars.antennas[ant].xmit = false self.vars.antennas[ant].mode = 0 self:ResetAntennaSpeedLock( ant ) -end +end --[[---------------------------------------------------------------------------------- - Radar captured vehicle functions + Radar captured vehicle functions ----------------------------------------------------------------------------------]]-- --- Returns the captured vehicles table +-- Returns the captured vehicles table function RADAR:GetCapturedVehicles() return self.vars.capturedVehicles end --- Resets the captured vehicles table to an empty table +-- Resets the captured vehicles table to an empty table function RADAR:ResetCapturedVehicles() self.vars.capturedVehicles = {} end @@ -1223,82 +1223,82 @@ end -- with the ray type for that vehicle data set (e.g. same or opp) function RADAR:InsertCapturedVehicleData( t, rt ) -- Make sure the table being passed is valid and not empty - if ( type( t ) == "table" and not UTIL:IsTableEmpty( t ) ) then - -- Iterate through the given table + if ( type( t ) == "table" and not UTIL:IsTableEmpty( t ) ) then + -- Iterate through the given table for _, v in pairs( t ) do -- Add the ray type to the current row - v.rayType = rt - - -- Insert it into the main captured vehicles table + v.rayType = rt + + -- Insert it into the main captured vehicles table table.insert( self.vars.capturedVehicles, v ) end - end -end + end +end --[[---------------------------------------------------------------------------------- - Radar dynamic sphere radius functions + Radar dynamic sphere radius functions ----------------------------------------------------------------------------------]]-- -- Returns the dynamic sphere data for the given key if there is any function RADAR:GetDynamicDataValue( key ) return self.vars.sphereSizes[key] -end - --- Returns if dynamic sphere data exists for the given key -function RADAR:DoesDynamicRadiusDataExist( key ) - return self:GetDynamicDataValue( key ) ~= nil end --- Sets the dynamic sohere data for the given key to the given table +-- Returns if dynamic sphere data exists for the given key +function RADAR:DoesDynamicRadiusDataExist( key ) + return self:GetDynamicDataValue( key ) ~= nil +end + +-- Sets the dynamic sohere data for the given key to the given table function RADAR:SetDynamicRadiusKey( key, t ) self.vars.sphereSizes[key] = t -end +end -- Inserts the given data into the dynamic spheres table, stores the radius and the actual summed up --- vehicle size. The key is just the model of a vehicle put into string form +-- vehicle size. The key is just the model of a vehicle put into string form function RADAR:InsertDynamicRadiusData( key, radius, actualSize ) -- Check to make sure there is no data for the vehicle - if ( self:GetDynamicDataValue( key ) == nil ) then + if ( self:GetDynamicDataValue( key ) == nil ) then -- Create a table to store the data in local data = {} - -- Put the data into the temporary table - data.radius = radius + -- Put the data into the temporary table + data.radius = radius data.actualSize = actualSize -- Set the dynamic sphere data for the vehicle self:SetDynamicRadiusKey( key, data ) - end -end + end +end --- Returns the dynamic sphere data for the given vehicle +-- Returns the dynamic sphere data for the given vehicle function RADAR:GetRadiusData( key ) return self.vars.sphereSizes[key].radius, self.vars.sphereSizes[key].actualSize -end +end --- This function is used to get the dynamic sphere data for a vehicle, if data already exists for the --- given vehicle, then the system just returns the already made data, otherwise the data gets created +-- This function is used to get the dynamic sphere data for a vehicle, if data already exists for the +-- given vehicle, then the system just returns the already made data, otherwise the data gets created function RADAR:GetDynamicRadius( veh ) - -- Get the model of the vehicle + -- Get the model of the vehicle local mdl = GetEntityModel( veh ) - - -- Create a key based on the model + + -- Create a key based on the model local key = tostring( mdl ) - + -- Check to see if data already exists local dataExists = self:DoesDynamicRadiusDataExist( key ) - - -- If the data doesn't already exist, then we create it - if ( not dataExists ) then - -- Get the min and max points of the vehicle model + + -- If the data doesn't already exist, then we create it + if ( not dataExists ) then + -- Get the min and max points of the vehicle model local min, max = GetModelDimensions( mdl ) - - -- Calculate the size, as the min value is negative - local size = max - min - + + -- Calculate the size, as the min value is negative + local size = max - min + -- Get a numeric size which composes of the x, y, and z size combined - local numericSize = size.x + size.y + size.z - + local numericSize = size.x + size.y + size.z + -- Get a dynamic radius for the given vehicle model that fits into the world of GTA local dynamicRadius = UTIL:Clamp( ( numericSize * numericSize ) / 12, 5.0, 11.0 ) @@ -1307,7 +1307,7 @@ function RADAR:GetDynamicRadius( veh ) -- Return the data return dynamicRadius, numericSize - end + end -- Return the stored data return self:GetRadiusData( key ) @@ -1315,57 +1315,57 @@ end --[[---------------------------------------------------------------------------------- - Radar functions + Radar functions ----------------------------------------------------------------------------------]]-- --- Takes a GTA speed and converts it into the type defined by the user in the operator menu +-- Takes a GTA speed and converts it into the type defined by the user in the operator menu function RADAR:GetVehSpeedConverted( speed ) -- Get the speed unit from the settings local unit = self:GetSettingValue( "speedType" ) - -- Return the coverted speed rounded to a whole number + -- Return the coverted speed rounded to a whole number return UTIL:Round( speed * self.speedConversions[unit], 0 ) -end +end --- Returns the validity of the given vehicle model +-- Returns the validity of the given vehicle model function RADAR:GetVehicleValidity( key ) return self.vars.validVehicles[key] -end +end --- Sets the validity for the given vehicle model +-- Sets the validity for the given vehicle model function RADAR:SetVehicleValidity( key, validity ) - self.vars.validVehicles[key] = validity -end + self.vars.validVehicles[key] = validity +end --- Returns if vehicle validity data exists for the given vehicle model +-- Returns if vehicle validity data exists for the given vehicle model function RADAR:DoesVehicleValidityExist( key ) - return self:GetVehicleValidity( key ) ~= nil -end + return self:GetVehicleValidity( key ) ~= nil +end -- Returns if the given vehicle is valid, as we don't want the radar to detect boats, helicopters, or planes! function RADAR:IsVehicleValid( veh ) - -- Get the model of the vehicle + -- Get the model of the vehicle local mdl = GetEntityModel( veh ) - - -- Create a key based on the model + + -- Create a key based on the model local key = tostring( mdl ) -- Check if the vehicle model is valid local valid = self:GetVehicleValidity( key ) - -- If the validity value hasn't been set for the vehicle model, then we do it now - if ( valid == nil ) then + -- If the validity value hasn't been set for the vehicle model, then we do it now + if ( valid == nil ) then -- If the model is not what we want, then set the validity to false - if ( IsThisModelABoat( mdl ) or IsThisModelAHeli( mdl ) or IsThisModelAPlane( mdl ) ) then + if ( IsThisModelABoat( mdl ) or IsThisModelAHeli( mdl ) or IsThisModelAPlane( mdl ) ) then self:SetVehicleValidity( key, false ) - return false - else - self:SetVehicleValidity( key, true ) - return true - end - end + return false + else + self:SetVehicleValidity( key, true ) + return true + end + end - return valid -end + return valid +end -- Gathers all of the vehicles in the local area of the player function RADAR:GetAllVehicles() @@ -1374,26 +1374,26 @@ function RADAR:GetAllVehicles() -- Iterate through vehicles for v in UTIL:EnumerateVehicles() do - if ( self:IsVehicleValid( v ) ) then - -- Insert the vehicle id into the temporary table + if ( self:IsVehicleValid( v ) ) then + -- Insert the vehicle id into the temporary table table.insert( t, v ) - end - end + end + end - -- Return the table + -- Return the table return t -end +end --- Used to check if an antennas mode fits with a ray type from the ray trace system +-- Used to check if an antennas mode fits with a ray type from the ray trace system function RADAR:CheckVehicleDataFitsMode( ant, rt ) -- Get the current mode value for the given antenna local mode = self:GetAntennaMode( ant ) -- Check that the given ray type matches up with the antenna's current mode - if ( ( mode == 3 ) or ( mode == 1 and rt == "same" ) or ( mode == 2 and rt == "opp" ) ) then return true end + if ( ( mode == 3 ) or ( mode == 1 and rt == "same" ) or ( mode == 2 and rt == "opp" ) ) then return true end -- Otherwise, return false as a last resort - return false + return false end -- This function is used to filter through the captured vehicles and work out what vehicles should be used for display @@ -1401,124 +1401,124 @@ end function RADAR:GetVehiclesForAntenna() -- Create the vehs table to store the split up captured vehicle data local vehs = { ["front"] = {}, ["rear"] = {} } - + -- Create the results table to store the vehicle results, the first index is for the 'strongest' vehicle and the -- second index is for the 'fastest' vehicle local results = { ["front"] = { nil, nil }, ["rear"] = { nil, nil } } - -- Loop through and split up the vehicles based on front and rear, this is simply because the actual system - -- that gets all of the vehicles hit by the radar only has a relative position of either 1 or -1, which we + -- Loop through and split up the vehicles based on front and rear, this is simply because the actual system + -- that gets all of the vehicles hit by the radar only has a relative position of either 1 or -1, which we -- then convert below into an antenna string! - for ant in UTIL:Values( { "front", "rear" } ) do + for ant in UTIL:Values( { "front", "rear" } ) do -- Check that the antenna is actually transmitting - if ( self:IsAntennaTransmitting( ant ) ) then + if ( self:IsAntennaTransmitting( ant ) ) then -- Iterate through the captured vehicles - for k, v in pairs( self:GetCapturedVehicles() ) do + for k, v in pairs( self:GetCapturedVehicles() ) do -- Convert the relative position to antenna text local antText = self:GetAntennaTextFromNum( v.relPos ) - -- Check the current vehicle's relative position is the same as the current antenna - if ( ant == antText ) then - -- Insert the vehicle into the table for the current antenna + -- Check the current vehicle's relative position is the same as the current antenna + if ( ant == antText ) then + -- Insert the vehicle into the table for the current antenna table.insert( vehs[ant], v ) - end - end + end + end -- As the radar is based on how the real Stalker DSR 2X works, we now sort the dataset by -- the 'strongest' (largest) target, this way the first result for the front and rear data - -- will be the one that gets displayed in the target boxes. + -- will be the one that gets displayed in the target boxes. table.sort( vehs[ant], self:GetStrongestSortFunc() ) end - end + end - -- Now that we have all of the vehicles split into front and rear, we can iterate through both sets and get + -- Now that we have all of the vehicles split into front and rear, we can iterate through both sets and get -- the strongest and fastest vehicle for display - for ant in UTIL:Values( { "front", "rear" } ) do - -- Check that the table for the current antenna is not empty + for ant in UTIL:Values( { "front", "rear" } ) do + -- Check that the table for the current antenna is not empty if ( not UTIL:IsTableEmpty( vehs[ant] ) ) then - -- Get the 'strongest' vehicle for the antenna - for k, v in pairs( vehs[ant] ) do + -- Get the 'strongest' vehicle for the antenna + for k, v in pairs( vehs[ant] ) do -- Check if the current vehicle item fits the mode set by the user - if ( self:CheckVehicleDataFitsMode( ant, v.rayType ) ) then - -- Set the result for the current antenna + if ( self:CheckVehicleDataFitsMode( ant, v.rayType ) ) then + -- Set the result for the current antenna results[ant][1] = v break - end - end + end + end -- Here we get the vehicle for the fastest section, but only if the user has the fast mode enabled - -- in the operator menu - if ( self:IsFastDisplayEnabled() ) then - -- Get the 'fastest' vehicle for the antenna + -- in the operator menu + if ( self:IsFastDisplayEnabled() ) then + -- Get the 'fastest' vehicle for the antenna table.sort( vehs[ant], self:GetFastestSortFunc() ) -- Create a temporary variable for the first result, reduces line length local temp = results[ant][1] -- Iterate through the vehicles for the current antenna - for k, v in pairs( vehs[ant] ) do + for k, v in pairs( vehs[ant] ) do -- When we grab a vehicle for the fastest section, as it is like how the real system works, there are a few - -- additional checks that have to be made - if ( self:CheckVehicleDataFitsMode( ant, v.rayType ) and v.veh ~= temp.veh and v.size < temp.size and v.speed > temp.speed + 1.0 ) then - -- Set the result for the current antenna - results[ant][2] = v + -- additional checks that have to be made + if ( self:CheckVehicleDataFitsMode( ant, v.rayType ) and v.veh ~= temp.veh and v.size < temp.size and v.speed > temp.speed + 1.0 ) then + -- Set the result for the current antenna + results[ant][2] = v break - end - end + end + end end - end + end end - -- Return the results + -- Return the results return { ["front"] = { results["front"][1], results["front"][2] }, ["rear"] = { results["rear"][1], results["rear"][2] } } -end +end --[[---------------------------------------------------------------------------------- NUI callback ----------------------------------------------------------------------------------]]-- --- Runs when the "Toggle Display" button is pressed on the remote control +-- Runs when the "Toggle Display" button is pressed on the remote control RegisterNUICallback( "toggleRadarDisplay", function( data, cb ) - -- Toggle the display state + -- Toggle the display state RADAR:ToggleDisplayState() cb( "ok" ) end ) --- Runs when the user presses the power button on the radar ui +-- Runs when the user presses the power button on the radar ui RegisterNUICallback( "togglePower", function( data, cb ) - if ( PLY:CanControlRadar() ) then - if ( not RADAR:IsPoweringUp() ) then - -- Toggle the radar's power + if ( PLY:CanControlRadar() ) then + if ( not RADAR:IsPoweringUp() ) then + -- Toggle the radar's power RADAR:TogglePower() SYNC:SendPowerState( RADAR:IsPowerOn() ) - end - end + end + end cb( "ok" ) end ) --- Runs when the user presses the ESC or RMB when the remote is open +-- Runs when the user presses the ESC or RMB when the remote is open RegisterNUICallback( "closeRemote", function( data, cb ) - -- Remove focus to the NUI side + -- Remove focus to the NUI side SetNuiFocus( false, false ) cb( "ok" ) end ) -- Runs when the user presses any of the antenna mode buttons on the remote -RegisterNUICallback( "setAntennaMode", function( data, cb ) - if ( PLY:CanControlRadar() ) then +RegisterNUICallback( "setAntennaMode", function( data, cb ) + if ( PLY:CanControlRadar() ) then -- Only run the codw if the radar has power and is not powering up - if ( RADAR:IsPowerOn() and not RADAR:IsPoweringUp() ) then - -- As the mode buttons are used to exit the menu, we check for that - if ( RADAR:IsMenuOpen() ) then + if ( RADAR:IsPowerOn() and not RADAR:IsPoweringUp() ) then + -- As the mode buttons are used to exit the menu, we check for that + if ( RADAR:IsMenuOpen() ) then -- Set the internal menu state to be closed (false) RADAR:SetMenuState( false ) - - -- Send a setting update to the NUI side + + -- Send a setting update to the NUI side RADAR:SendSettingUpdate() - - -- Play a menu done beep + + -- Play a menu done beep SendNUIMessage( { _type = "audio", name = "done", vol = RADAR:GetSettingValue( "beep" ) } ) -- Save the operator menu values @@ -1527,66 +1527,66 @@ RegisterNUICallback( "setAntennaMode", function( data, cb ) else -- Change the mode for the designated antenna, pass along a callback which contains data from this NUI callback RADAR:SetAntennaMode( data.value, tonumber( data.mode ), function() - -- Update the interface with the new mode + -- Update the interface with the new mode SendNUIMessage( { _type = "antennaMode", ant = data.value, mode = tonumber( data.mode ) } ) - - -- Play a beep + + -- Play a beep SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) -- Sync SYNC:SendAntennaMode( data.value, tonumber( data.mode ) ) end ) - end + end end - end + end - cb( "ok" ) + cb( "ok" ) end ) --- Runs when the user presses either of the XMIT/HOLD buttons on the remote -RegisterNUICallback( "toggleAntenna", function( data, cb ) - if ( PLY:CanControlRadar() ) then +-- Runs when the user presses either of the XMIT/HOLD buttons on the remote +RegisterNUICallback( "toggleAntenna", function( data, cb ) + if ( PLY:CanControlRadar() ) then -- Only run the codw if the radar has power and is not powering up if ( RADAR:IsPowerOn() and not RADAR:IsPoweringUp() ) then - -- As the xmit/hold buttons are used to change settings in the menu, we check for that - if ( RADAR:IsMenuOpen() ) then + -- As the xmit/hold buttons are used to change settings in the menu, we check for that + if ( RADAR:IsMenuOpen() ) then -- Change the menu option based on which button is pressed RADAR:ChangeMenuOption( data.value ) - - -- Play a beep noise + + -- Play a beep noise SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) else -- Toggle the transmit state for the designated antenna, pass along a callback which contains data from this NUI callback RADAR:ToggleAntenna( data.value, function() -- Update the interface with the new antenna transmit state SendNUIMessage( { _type = "antennaXmit", ant = data.value, on = RADAR:IsAntennaTransmitting( data.value ) } ) - + -- Play some audio specific to the transmit state SendNUIMessage( { _type = "audio", name = RADAR:IsAntennaTransmitting( data.value ) and "xmit_on" or "xmit_off", vol = RADAR:GetSettingValue( "beep" ) } ) -- Sync SYNC:SendAntennaPowerState( RADAR:IsAntennaTransmitting( data.value ), data.value ) end ) - end + end end - end + end - cb( "ok" ) + cb( "ok" ) end ) -- Runs when the user presses the menu button on the remote control RegisterNUICallback( "menu", function( data, cb ) - if ( PLY:CanControlRadar() ) then + if ( PLY:CanControlRadar() ) then -- Only run the codw if the radar has power and is not powering up - if ( RADAR:IsPowerOn() and not RADAR:IsPoweringUp() ) then + if ( RADAR:IsPowerOn() and not RADAR:IsPoweringUp() ) then -- As the menu button is a multipurpose button, we first check to see if the menu is already open - if ( RADAR:IsMenuOpen() ) then + if ( RADAR:IsMenuOpen() ) then -- As the menu is already open, we then iterate to the next option in the settings list RADAR:ChangeMenuIndex() - else + else -- Set the menu state to open, which will prevent anything else within the radar from working RADAR:SetMenuState( true ) - + -- Send an update to the NUI side RADAR:SendMenuUpdate() end @@ -1594,126 +1594,126 @@ RegisterNUICallback( "menu", function( data, cb ) -- Play the standard audio beep SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) end - end + end - cb( "ok" ) + cb( "ok" ) end ) --- Runs when the JavaScript side sends the UI data for saving +-- Runs when the JavaScript side sends the UI data for saving RegisterNUICallback( "saveUiData", function( data, cb ) UTIL:Log( "Saving updated UI settings data." ) SetResourceKvp( "wk_wars2x_ui_data", json.encode( data ) ) - cb( "ok" ) + cb( "ok" ) end ) -- Runs when the JavaScript side sends the quick start video has been watched RegisterNUICallback( "qsvWatched", function( data, cb ) SetResourceKvpInt( "wk_wars2x_new_user", 1 ) - cb( "ok" ) + cb( "ok" ) end ) --[[---------------------------------------------------------------------------------- - Main threads + Main threads ----------------------------------------------------------------------------------]]-- --- Some people might not like the idea of the resource having a CPU MSEC over 0.10, but due to the functions +-- Some people might not like the idea of the resource having a CPU MSEC over 0.10, but due to the functions -- and the way the whole radar system works, it will use over 0.10 a decent amount. In this function, we --- dynamically adjust the wait time in the main thread, so that when the player is driving their vehicle and --- moving, the system doesn't run as fast so as to use less CPU time. When they have their vehicle +-- dynamically adjust the wait time in the main thread, so that when the player is driving their vehicle and +-- moving, the system doesn't run as fast so as to use less CPU time. When they have their vehicle -- stationary, the system runs more often, which means that if a situation occurs such as a vehicle flying --- past them at a high rate of speed, the system will be able to pick it up as it is running faster. Also, as --- the user is stationary, if the system takes up an additional one or two frames per second, it won't really +-- past them at a high rate of speed, the system will be able to pick it up as it is running faster. Also, as +-- the user is stationary, if the system takes up an additional one or two frames per second, it won't really -- be noticeable. function RADAR:RunDynamicThreadWaitCheck() -- Get the speed of the local players vehicle local speed = self:GetPatrolSpeed() -- Check that the vehicle speed is less than 0.1 - if ( speed < 0.1 ) then + if ( speed < 0.1 ) then -- Change the thread wait time to 200 ms, the trace system will now run five times per second self:SetThreadWaitTime( 200 ) - else + else -- Change the thread wait time to 500 ms, the trace system will now run two times a second self:SetThreadWaitTime( 500 ) - end -end + end +end -- Create the thread that will run the dynamic thread wait check, this check only runs every two seconds Citizen.CreateThread( function() - while ( true ) do + while ( true ) do -- Run the function RADAR:RunDynamicThreadWaitCheck() -- Make the thread wait two seconds Citizen.Wait( 2000 ) - end + end end ) -- This function handles the custom ray trace system that is used to gather all of the vehicles hit by --- the ray traces defined in RADAR.rayTraces. +-- the ray traces defined in RADAR.rayTraces. function RADAR:RunThreads() - -- For the system to even run, the player needs to be sat in the driver's seat of a class 18 vehicle, the + -- For the system to even run, the player needs to be sat in the driver's seat of a class 18 vehicle, the -- radar has to be visible and the power must be on, and either one of the antennas must be enabled. - if ( PLY:CanViewRadar() and self:CanPerformMainTask() and self:IsEitherAntennaOn() ) then - -- Before we create any of the custom ray trace threads, we need to make sure that the ray trace state + if ( PLY:CanViewRadar() and self:CanPerformMainTask() and self:IsEitherAntennaOn() ) then + -- Before we create any of the custom ray trace threads, we need to make sure that the ray trace state -- is at zero, if it is not at zero, then it means the system is still currently tracing - if ( self:GetRayTraceState() == 0 ) then + if ( self:GetRayTraceState() == 0 ) then -- Grab a copy of the vehicle pool local vehs = self:GetVehiclePool() -- Reset the main captured vehicles table self:ResetCapturedVehicles() - + -- Here we run the function that creates all of the main ray threads self:CreateRayThreads( PLY.veh, vehs ) -- Make the thread this function runs in wait the dynamic time defined by the system Citizen.Wait( self:GetThreadWaitTime() ) - - -- If the current ray trace state is the same as the total number of rays, then we reset the ray trace + + -- If the current ray trace state is the same as the total number of rays, then we reset the ray trace -- state back to 0 so the thread system can run again - elseif ( self:GetRayTraceState() == self:GetNumOfRays() ) then + elseif ( self:GetRayTraceState() == self:GetNumOfRays() ) then -- Reset the ray trace state to 0 self:ResetRayTraceState() end - end -end + end +end -- Create the main thread that will run the threads function, the function itself is run every frame as the -- dynamic wait time is ran inside the function Citizen.CreateThread( function() - while ( true ) do + while ( true ) do -- Run the function RADAR:RunThreads() -- Make the thread wait 0 ms Citizen.Wait( 0 ) - end + end end ) --- This is the main function that runs and handles all information that is sent to the NUI side for display, all +-- This is the main function that runs and handles all information that is sent to the NUI side for display, all -- speed values are converted on the Lua side into a format that is displayable using the custom font on the NUI side function RADAR:Main() -- Only run any of the main code if all of the states are met, player in the driver's seat of a class 18 vehicle, and - -- the system has to be able to perform main tasks - if ( PLY:CanViewRadar() and self:CanPerformMainTask() ) then + -- the system has to be able to perform main tasks + if ( PLY:CanViewRadar() and self:CanPerformMainTask() ) then -- Create a table that will be used to store all of the data to be sent to the NUI side - local data = {} + local data = {} -- Get the player's vehicle speed local entSpeed = GetEntitySpeed( PLY.veh ) - + -- Set the internal patrol speed to the speed obtained above, this is then used in the dynamic thread wait calculation self:SetPatrolSpeed( entSpeed ) - -- Change what is displayed in the patrol speed box on the radar interface depending on if the players vehicle is + -- Change what is displayed in the patrol speed box on the radar interface depending on if the players vehicle is -- stationary or moving - if ( entSpeed == 0 ) then + if ( entSpeed == 0 ) then data.patrolSpeed = "¦[]" - else + else local speed = self:GetVehSpeedConverted( entSpeed ) data.patrolSpeed = UTIL:FormatSpeed( speed ) - end + end -- Get the vehicles to be displayed for the antenna, then we take the results from that and send the relevant -- information to the NUI side @@ -1721,75 +1721,75 @@ function RADAR:Main() data.antennas = { ["front"] = nil, ["rear"] = nil } -- Iterate through the front and rear data and obtain the information to be displayed - for ant in UTIL:Values( { "front", "rear" } ) do + for ant in UTIL:Values( { "front", "rear" } ) do -- Check that the antenna is actually transmitting, no point in running all the checks below if the antenna is off if ( self:IsAntennaTransmitting( ant ) ) then - -- Create a table for the current antenna to store the information + -- Create a table for the current antenna to store the information data.antennas[ant] = {} - -- When the system works out what vehicles to be used, both the "front" and "rear" keys have two items located + -- When the system works out what vehicles to be used, both the "front" and "rear" keys have two items located -- at index 1 and 2. Index 1 stores the vehicle data for the antenna's 'strongest' vehicle, and index 2 stores - -- the vehicle data for the 'fastest' vehicle. Here we iterate through both the indexes and just run checks to + -- the vehicle data for the 'fastest' vehicle. Here we iterate through both the indexes and just run checks to -- see if it is a particular type (e.g. if i % 2 == 0 then it's the 'fastest' vehicle) - for i = 1, 2 do - -- Create the table to store the speed and direction for this vehicle data + for i = 1, 2 do + -- Create the table to store the speed and direction for this vehicle data data.antennas[ant][i] = { speed = "¦¦¦", dir = 0 } - -- If the current iteration is the number 2 ('fastest') and there's a speed locked, grab the locked speed + -- If the current iteration is the number 2 ('fastest') and there's a speed locked, grab the locked speed -- and direction - if ( i == 2 and self:IsAntennaSpeedLocked( ant ) ) then + if ( i == 2 and self:IsAntennaSpeedLocked( ant ) ) then data.antennas[ant][i].speed = self:GetAntennaLockedSpeed( ant ) data.antennas[ant][i].dir = self:GetAntennaLockedDir( ant ) - - -- Otherwise, continue with getting speed and direction data - else - -- The vehicle data exists for this slot - if ( av[ant][i] ~= nil ) then + + -- Otherwise, continue with getting speed and direction data + else + -- The vehicle data exists for this slot + if ( av[ant][i] ~= nil ) then -- Here we get the entity speed of the vehicle, the speed for this vehicle would've been obtained -- and stored in the trace stage, but the speed would've only been obtained and stored once, which -- means that it woulsn't be the current speed local vehSpeed = GetEntitySpeed( av[ant][i].veh ) local convertedSpeed = self:GetVehSpeedConverted( vehSpeed ) - data.antennas[ant][i].speed = UTIL:FormatSpeed( convertedSpeed ) + data.antennas[ant][i].speed = UTIL:FormatSpeed( convertedSpeed ) - -- Work out if the vehicle is closing or away + -- Work out if the vehicle is closing or away local ownH = UTIL:Round( GetEntityHeading( PLY.veh ), 0 ) local tarH = UTIL:Round( GetEntityHeading( av[ant][i].veh ), 0 ) data.antennas[ant][i].dir = UTIL:GetEntityRelativeDirection( ownH, tarH ) - -- Set the internal antenna data as this actual dataset is valid - if ( i % 2 == 0 ) then + -- Set the internal antenna data as this actual dataset is valid + if ( i % 2 == 0 ) then self:SetAntennaFastData( ant, data.antennas[ant][i].speed, data.antennas[ant][i].dir ) - else + else self:SetAntennaData( ant, data.antennas[ant][i].speed, data.antennas[ant][i].dir ) end - + -- Lock the speed automatically if the fast limit system is allowed - if ( self:IsFastLimitAllowed() ) then + if ( self:IsFastLimitAllowed() ) then -- Make sure the speed is larger than the limit, and that there isn't already a locked speed - if ( self:IsFastLockEnabled() and convertedSpeed > self:GetFastLimit() and not self:IsAntennaSpeedLocked( ant ) ) then - if ( ( self:OnlyLockFastPlayers() and UTIL:IsPlayerInVeh( av[ant][i].veh ) ) or not self:OnlyLockFastPlayers() ) then + if ( self:IsFastLockEnabled() and convertedSpeed > self:GetFastLimit() and not self:IsAntennaSpeedLocked( ant ) ) then + if ( ( self:OnlyLockFastPlayers() and UTIL:IsPlayerInVeh( av[ant][i].veh ) ) or not self:OnlyLockFastPlayers() ) then self:LockAntennaSpeed( ant ) - end - end - end - else + end + end + end + else -- If the active vehicle is not valid, we reset the internal data - if ( i % 2 == 0 ) then + if ( i % 2 == 0 ) then self:SetAntennaFastData( ant, nil, nil ) - else + else self:SetAntennaData( ant, nil, nil ) end - end - end - end - end - end + end + end + end + end + end -- Send the update to the NUI side SendNUIMessage( { _type = "update", speed = data.patrolSpeed, antennas = data.antennas } ) - end -end + end +end -- Main thread Citizen.CreateThread( function() @@ -1798,19 +1798,19 @@ Citizen.CreateThread( function() -- Run the function to cache the number of rays, this way a hard coded number is never needed RADAR:CacheNumRays() - + -- Update the end coordinates for the ray traces based on the config, again, reduced hard coding RADAR:UpdateRayEndCoords() - + -- Update the operator menu positions RADAR:UpdateOptionIndexes() -- If the fast limit feature is allowed, create the config in the radar variables - if ( RADAR:IsFastLimitAllowed() ) then + if ( RADAR:IsFastLimitAllowed() ) then RADAR:CreateFastLimitConfig() - end + end - -- Run the main radar function + -- Run the main radar function while ( true ) do RADAR:Main() @@ -1818,51 +1818,51 @@ Citizen.CreateThread( function() end end ) --- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not --- using it. Hides the radar UI when certain criteria is met, e.g. in pause menu or stepped out ot the --- patrol vehicle +-- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not +-- using it. Hides the radar UI when certain criteria is met, e.g. in pause menu or stepped out ot the +-- patrol vehicle function RADAR:RunDisplayValidationCheck() if ( ( ( PLY.veh == 0 or ( PLY.veh > 0 and not PLY.vehClassValid ) ) and self:GetDisplayState() and not self:GetDisplayHidden() ) or IsPauseMenuActive() and self:GetDisplayState() ) then - self:SetDisplayHidden( true ) + self:SetDisplayHidden( true ) SendNUIMessage( { _type = "setRadarDisplayState", state = false } ) elseif ( PLY:CanViewRadar() and self:GetDisplayState() and self:GetDisplayHidden() ) then - self:SetDisplayHidden( false ) + self:SetDisplayHidden( false ) SendNUIMessage( { _type = "setRadarDisplayState", state = true } ) - end + end end -- Runs the display validation check for the radar -Citizen.CreateThread( function() +Citizen.CreateThread( function() Citizen.Wait( 100 ) - while ( true ) do - -- Run the check + while ( true ) do + -- Run the check RADAR:RunDisplayValidationCheck() - -- Wait half a second + -- Wait half a second Citizen.Wait( 500 ) - end + end end ) -- Update the vehicle pool every 3 seconds function RADAR:UpdateVehiclePool() - -- Only update the vehicle pool if we need to - if ( PLY:CanViewRadar() and self:CanPerformMainTask() and self:IsEitherAntennaOn() ) then + -- Only update the vehicle pool if we need to + if ( PLY:CanViewRadar() and self:CanPerformMainTask() and self:IsEitherAntennaOn() ) then -- Get the active vehicle set local vehs = self:GetAllVehicles() - - -- Update the vehicle pool + + -- Update the vehicle pool self:SetVehiclePool( vehs ) - end -end + end +end -- Runs the vehicle pool updater -Citizen.CreateThread( function() +Citizen.CreateThread( function() while ( true ) do - -- Update the vehicle pool + -- Update the vehicle pool RADAR:UpdateVehiclePool() -- Wait 3 seconds Citizen.Wait( 3000 ) - end + end end ) \ No newline at end of file diff --git a/cl_sync.lua b/cl_sync.lua index 6ca4b29..eb4d71d 100644 --- a/cl_sync.lua +++ b/cl_sync.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -34,35 +34,35 @@ SYNC = {} --[[---------------------------------------------------------------------------------- - Sync functions + Sync functions ----------------------------------------------------------------------------------]]-- function SYNC:SyncData( cb ) local otherPed = PLY:GetOtherPed() - if ( otherPed ~= nil and otherPed ~= 0 ) then + if ( otherPed ~= nil and otherPed ~= 0 ) then local otherPly = GetPlayerServerId( NetworkGetPlayerIndexFromPed( otherPed ) ) cb( otherPly ) - end -end + end +end function SYNC:SendPowerState( state ) self:SyncData( function( ply ) TriggerServerEvent( "wk_wars2x_sync:sendPowerState", ply, state ) end ) -end +end function SYNC:SendAntennaPowerState( state, ant ) self:SyncData( function( ply ) TriggerServerEvent( "wk_wars2x_sync:sendAntennaPowerState", ply, state, ant ) end ) -end +end function SYNC:SendAntennaMode( ant, mode ) self:SyncData( function( ply ) TriggerServerEvent( "wk_wars2x_sync:sendAntennaMode", ply, ant, mode ) end ) -end +end --[[---------------------------------------------------------------------------------- @@ -72,35 +72,35 @@ RegisterNetEvent( "wk_wars2x_sync:receivePowerState" ) AddEventHandler( "wk_wars2x_sync:receivePowerState", function( state ) local power = RADAR:IsPowerOn() - if ( power ~= state ) then + if ( power ~= state ) then Citizen.SetTimeout( 100, function() RADAR:TogglePower() end ) - end + end end ) RegisterNetEvent( "wk_wars2x_sync:receiveAntennaPowerState" ) AddEventHandler( "wk_wars2x_sync:receiveAntennaPowerState", function( state, antenna ) local power = RADAR:IsAntennaTransmitting( antenna ) - if ( power ~= state ) then + if ( power ~= state ) then RADAR:ToggleAntenna( antenna, function() -- Update the interface with the new antenna transmit state SendNUIMessage( { _type = "antennaXmit", ant = antenna, on = state } ) - + -- Play some audio specific to the transmit state SendNUIMessage( { _type = "audio", name = state and "xmit_on" or "xmit_off", vol = RADAR:GetSettingValue( "beep" ) } ) end ) - end + end end ) RegisterNetEvent( "wk_wars2x_sync:receiveAntennaMode" ) AddEventHandler( "wk_wars2x_sync:receiveAntennaMode", function( antenna, mode ) RADAR:SetAntennaMode( antenna, mode, function() - -- Update the interface with the new mode + -- Update the interface with the new mode SendNUIMessage( { _type = "antennaMode", ant = antenna, mode = mode } ) - - -- Play a beep + + -- Play a beep SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) end ) end ) \ No newline at end of file diff --git a/cl_test_cmds.lua b/cl_test_cmds.lua index 8c3028b..3fb57aa 100644 --- a/cl_test_cmds.lua +++ b/cl_test_cmds.lua @@ -1,4 +1,4 @@ -if ( CONFIG.debug ) then +if ( CONFIG.debug ) then -- Restart the resource RegisterCommand( "rre", function( source, args, rawCommand ) UTIL:Notify( "[DEBUG]: Restarting resource" ) diff --git a/cl_utils.lua b/cl_utils.lua index b722741..f780021 100644 --- a/cl_utils.lua +++ b/cl_utils.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -35,49 +35,49 @@ UTIL = {} -- Returns a number to a set number of decimal places function UTIL:Round( num, numDecimalPlaces ) return tonumber( string.format( "%." .. ( numDecimalPlaces or 0 ) .. "f", num ) ) -end +end --- The custom font used for the digital displays have the ¦ symbol as an empty character, this function --- takes a speed and returns a formatted speed that can be displayed on the radar +-- The custom font used for the digital displays have the ¦ symbol as an empty character, this function +-- takes a speed and returns a formatted speed that can be displayed on the radar function UTIL:FormatSpeed( speed ) - -- Return "Err" (Error) if the given speed is outside the 0-999 range - if ( speed < 0 or speed > 999 ) then return "Err" end + -- Return "Err" (Error) if the given speed is outside the 0-999 range + if ( speed < 0 or speed > 999 ) then return "Err" end - -- Convert the speed to a string + -- Convert the speed to a string local text = tostring( speed ) local pipes = "" -- Create a string of pipes (¦) for the number of spaces - for i = 1, 3 - string.len( text ) do + for i = 1, 3 - string.len( text ) do pipes = pipes .. "¦" - end - + end + -- Return the formatted speed return pipes .. text -end +end --- Returns a clamped numerical value based on the given parameters +-- Returns a clamped numerical value based on the given parameters function UTIL:Clamp( val, min, max ) -- Return the min value if the given value is less than the min - if ( val < min ) then - return min + if ( val < min ) then + return min -- Return the max value if the given value is larger than the max - elseif ( val > max ) then - return max - end + elseif ( val > max ) then + return max + end -- Return the given value if it's between the min and max - return val -end + return val +end -- Returns if the given table is empty, includes numerical and non-numerical key values function UTIL:IsTableEmpty( t ) - local c = 0 + local c = 0 - for _ in pairs( t ) do c = c + 1 end + for _ in pairs( t ) do c = c + 1 end return c == 0 -end +end -- Credit to Deltanic for this function function UTIL:Values( xs ) @@ -96,16 +96,16 @@ function UTIL:GetVehicleInDirection( entFrom, coordFrom, coordTo ) return vehicle end --- Returns if a target vehicle is coming towards or going away from the patrol vehicle, it has a range --- so if a vehicle is sideways compared to the patrol vehicle, the directional arrows won't light up +-- Returns if a target vehicle is coming towards or going away from the patrol vehicle, it has a range +-- so if a vehicle is sideways compared to the patrol vehicle, the directional arrows won't light up function UTIL:GetEntityRelativeDirection( myAng, tarAng ) local angleDiff = math.abs( ( myAng - tarAng + 180 ) % 360 - 180 ) - if ( angleDiff < 45 ) then + if ( angleDiff < 45 ) then return 1 - elseif ( angleDiff > 135 ) then + elseif ( angleDiff > 135 ) then return 2 - end + end return 0 end @@ -115,15 +115,15 @@ function UTIL:IsPlayerInVeh( veh ) for i = -1, GetVehicleMaxNumberOfPassengers( veh ) + 1, 1 do local ped = GetPedInVehicleSeat( veh, i ) - if ( DoesEntityExist( ped ) ) then - if ( IsPedAPlayer( ped ) ) then return true end - end - end + if ( DoesEntityExist( ped ) ) then + if ( IsPedAPlayer( ped ) ) then return true end + end + end return false -end +end --- Your everyday GTA notification function +-- Your everyday GTA notification function function UTIL:Notify( text ) SetNotificationTextEntry( "STRING" ) AddTextComponentSubstringPlayerName( text ) @@ -132,7 +132,7 @@ end function UTIL:Log( msg ) print( "[Wraith ARS 2X]: " .. msg ) -end +end function UTIL:DrawDebugText( x, y, scale, centre, text ) SetTextFont( 4 ) @@ -151,7 +151,7 @@ end function UTIL:IsResourceNameValid() return GetCurrentResourceName() == "wk_wars2x" -end +end --[[The MIT License (MIT) diff --git a/config.lua b/config.lua index 1cfbd31..09e25f9 100644 --- a/config.lua +++ b/config.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -37,39 +37,39 @@ CONFIG = {} CONFIG.debug = true -- Radar fast limit locking --- When enabled, the player will be able to define a fast limit within the radar's menu, when a vehicle +-- When enabled, the player will be able to define a fast limit within the radar's menu, when a vehicle -- exceeds the fast limit, it will be locked into the fast box. Default setting is disabled to maintain realism -CONFIG.allow_fast_limit = true +CONFIG.allow_fast_limit = true --- Radar only lock playersw with auto fast locking --- When enabled, the radar will only automatically lock a speed if the caught vehicle has a real player in it. -CONFIG.only_lock_players = false +-- Radar only lock playersw with auto fast locking +-- When enabled, the radar will only automatically lock a speed if the caught vehicle has a real player in it. +CONFIG.only_lock_players = false -- In-game first time quick start video --- When enabled, the player will be asked if they'd like to view the quick start video the first time they --- open the remote. -CONFIG.allow_quick_start_video = true +-- When enabled, the player will be asked if they'd like to view the quick start video the first time they +-- open the remote. +CONFIG.allow_quick_start_video = true -- Allow passenger view -- When enabled, the front seat passenger will be able to view the radar and plate reader from their end. CONFIG.allow_passenger_view = true -- Allow passenger control --- Dependent on CONFIG.allow_passenger_view. When enabled, the front seat passenger will be able to open the --- radar remote and control the radar and plate reader for themself and the driver. +-- Dependent on CONFIG.allow_passenger_view. When enabled, the front seat passenger will be able to open the +-- radar remote and control the radar and plate reader for themself and the driver. CONFIG.allow_passenger_control = false --- Set this to true if you use Sonoran CAD with the WraithV2 plugin -CONFIG.use_sonorancad = false +-- Set this to true if you use Sonoran CAD with the WraithV2 plugin +CONFIG.use_sonorancad = false -- Sets the defaults of all keybinds -- These keybinds can be changed by each person in their GTA Settings->Keybinds->FiveM CONFIG.keyDefaults = { - -- Remote control key + -- Remote control key remote_control = "f5", - -- Radar key lock key + -- Radar key lock key key_lock = "l", -- Radar front antenna lock/unlock Key @@ -86,32 +86,32 @@ CONFIG.keyDefaults = } -- Here you can change the default values for the operator menu, do note, if any of these values are not --- one of the options listed, the script will not work. -CONFIG.menuDefaults = +-- one of the options listed, the script will not work. +CONFIG.menuDefaults = { -- Should the system calculate and display faster targets -- Options: true or false - ["fastDisplay"] = true, + ["fastDisplay"] = true, -- Sensitivity for each radar mode, this changes how far the antennas will detect vehicles -- Options: 0.2, 0.4, 0.6, 0.8, 1.0 - ["same"] = 0.6, - ["opp"] = 0.6, + ["same"] = 0.6, + ["opp"] = 0.6, - -- The volume of the audible beep - -- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 + -- The volume of the audible beep + -- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 ["beep"] = 0.6, - - -- The volume of the verbal lock confirmation - -- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 + + -- The volume of the verbal lock confirmation + -- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 ["voice"] = 0.6, - - -- The volume of the plate reader audio - -- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 - ["plateAudio"] = 0.6, + + -- The volume of the plate reader audio + -- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 + ["plateAudio"] = 0.6, -- The speed unit used in conversions - -- Options: mph or kmh + -- Options: mph or kmh ["speedType"] = "mph" } @@ -122,12 +122,12 @@ CONFIG.uiDefaults = -- Options: 0.25 - 2.5 scale = { - radar = 1.0, - remote = 1.0, + radar = 1.0, + remote = 1.0, plateReader = 1.0 - }, + }, -- The safezone size, must be a multiple of 5. -- Options: 0 - 100 - safezone = 20 + safezone = 20 } \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index 63bb4ab..0d4fb39 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -42,9 +42,9 @@ version "beta" -- Include the files files { - "nui/radar.html", - "nui/radar.css", - "nui/jquery-3.4.1.min.js", + "nui/radar.html", + "nui/radar.css", + "nui/jquery-3.4.1.min.js", "nui/radar.js", "nui/images/*.png", "nui/images/plates/*.png", diff --git a/sv_version_check.lua b/sv_version_check.lua index 304b9e8..134cb0d 100644 --- a/sv_version_check.lua +++ b/sv_version_check.lua @@ -2,10 +2,10 @@ Wraith ARS 2X Created by WolfKnight - - For discussions, information on future updates, and more, join - my Discord: https://discord.gg/fD4e6WD - + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + MIT License Copyright (c) 2020-2021 WolfKnight @@ -31,7 +31,7 @@ ---------------------------------------------------------------------------------------]]-- -- Branding! -local label = +local label = [[ // || __ __ _ _ _ _____ _____ ___ __ __ @@ -47,37 +47,37 @@ local label = -- Returns the current version set in fxmanifest.lua function GetCurrentVersion() return GetResourceMetadata( GetCurrentResourceName(), "version" ) -end +end -- Grabs the latest version number from the web GitHub PerformHttpRequest( "https://wolfknight98.github.io/wk_wars2x_web/version.txt", function( err, text, headers ) - -- Wait to reduce spam + -- Wait to reduce spam Citizen.Wait( 2000 ) -- Print the branding! print( label ) - -- Get the current resource version + -- Get the current resource version local curVer = GetCurrentVersion() - - if ( text ~= nil ) then - -- Print out the current and latest version + + if ( text ~= nil ) then + -- Print out the current and latest version print( " || Current version: " .. curVer ) print( " || Latest recommended version: " .. text .."\n ||" ) - + -- If the versions are different, print it out if ( text ~= curVer ) then print( " || ^1Your Wraith ARS 2X version is outdated, visit the FiveM forum post to get the latest version.\n^0 \\\\\n" ) else print( " || ^2Wraith ARS 2X is up to date!\n^0 ||\n \\\\\n" ) end - else + else -- In case the version can not be requested, print out an error message print( " || ^1There was an error getting the latest version information, if the issue persists contact WolfKnight#8586 on Discord.\n^0 ||\n \\\\\n" ) - end + end - -- Warn the console if the resource has been renamed, as this will cause issues with the resource's functionality. - if ( GetCurrentResourceName() ~= "wk_wars2x" ) then + -- Warn the console if the resource has been renamed, as this will cause issues with the resource's functionality. + if ( GetCurrentResourceName() ~= "wk_wars2x" ) then print( "^1ERROR: Resource name is not wk_wars2x, expect there to be issues with the resource. To ensure there are no issues, please leave the resource name as wk_wars2x^0\n\n" ) - end + end end ) \ No newline at end of file