diff --git a/cl_plate_reader.lua b/cl_plate_reader.lua index c83e1c8..8043c88 100644 --- a/cl_plate_reader.lua +++ b/cl_plate_reader.lua @@ -1,9 +1,34 @@ ---[[----------------------------------------------------------------------- +--[[--------------------------------------------------------------------------------------- Wraith ARS 2X Created by WolfKnight + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + + MIT License ------------------------------------------------------------------------]]-- + Copyright (c) 2020 WolfKnight + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +---------------------------------------------------------------------------------------]]-- READER = {} @@ -15,32 +40,32 @@ READER = {} ----------------------------------------------------------------------------------]]-- 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, + hidden = false, - -- 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 - }, + -- 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 + }, - -- 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 - } - } + -- 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 + } + } } -- Gets the display state @@ -69,75 +94,85 @@ end -- Returns the stored plate for the given reader function READER:GetPlate( cam ) - return self.vars.cams[cam].plate + return self.vars.cams[cam].plate end -- Sets the plate for the given reader to the given plate function READER:SetPlate( cam, plate ) - self.vars.cams[cam].plate = plate + 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 + return self.vars.cams[cam].index end -- Sets the plate index for the given reader to the given index function READER:SetIndex( cam, index ) - self.vars.cams[cam].index = index + self.vars.cams[cam].index = index end -- Returns the bolo plate function READER:GetBoloPlate() - return self.vars.boloPlate + return self.vars.boloPlate end -- Sets the bolo plate to the given plate function READER:SetBoloPlate( plate ) - self.vars.boloPlate = plate - UTIL:Notify( "BOLO plate set to: " .. plate ) + self.vars.boloPlate = plate + UTIL:Notify( "BOLO plate set to: " .. plate ) end -- Returns if the given reader is locked function READER:GetCamLocked( cam ) - return self.vars.cams[cam].locked + return self.vars.cams[cam].locked end -- Locks the given reader -function READER:LockCam( cam, playAudio, isBolo ) - -- Check that plate readers can actually be locked - if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then - -- Toggle the lock state - self.vars.cams[cam].locked = not self.vars.cams[cam].locked +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 + self.vars.cams[cam].locked = not self.vars.cams[cam].locked - -- Tell the NUI side to show/hide the lock icon - SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ), isBolo = isBolo } ) + -- 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 ( playAudio ) then - SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "plateAudio" ) } ) - end - - TriggerEvent( "wk:onPlateLocked", cam, self:GetPlate( cam ), self:GetIndex( cam ) ) + if ( self:GetCamLocked( cam ) ) then + if ( playBeep ) then + SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "plateAudio" ) } ) + end + + if ( isBolo ) then + SendNUIMessage( { _type = "audio", name = "plate_hit", vol = RADAR:GetSettingValue( "plateAudio" ) } ) + 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 -- Returns if the plate reader system can perform tasks function READER:CanPerformMainTask() - return self.vars.displayed and not self.vars.hidden + return self.vars.displayed and not self.vars.hidden end -- Returns if the given relative position value is for front or rear function READER:GetCamFromNum( relPos ) - if ( relPos == 1 ) then - return "front" - elseif ( relPos == -1 ) then - return "rear" - end + if ( relPos == 1 ) then + return "front" + elseif ( relPos == -1 ) then + return "rear" + 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 RegisterNUICallback( "togglePlateReaderDisplay", function() -- Toggle the display state @@ -146,85 +181,85 @@ end ) -- Runs when the "Set BOLO Plate" button is pressed on the plate reader box RegisterNUICallback( "setBoloPlate", function( plate, cb ) - -- Set the BOLO plate - READER:SetBoloPlate( plate ) + -- Set the BOLO plate + READER:SetBoloPlate( plate ) 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 - -- Loop through front (1) and rear (-1) - for i = 1, -1, -2 do - -- Get the world position of the player's vehicle - local pos = GetEntityCoords( PLY.veh ) + -- 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 + -- Get the world position of the player's vehicle + local pos = GetEntityCoords( PLY.veh ) - -- Get a start position 5m in front/behind the player's vehicle - local start = GetOffsetFromEntityInWorldCoords( PLY.veh, 0.0, ( 5.0 * i ), 0.0 ) + -- Get a start position 5m in front/behind the player's vehicle + local start = GetOffsetFromEntityInWorldCoords( PLY.veh, 0.0, ( 5.0 * i ), 0.0 ) - -- Get the end position 40m in front/behind the player's vehicle - local offset = GetOffsetFromEntityInWorldCoords( PLY.veh, -2.5, ( 50.0 * i ), 0.0 ) + -- 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 - local veh = UTIL:GetVehicleInDirection( PLY.veh, start, offset ) + -- 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 - -- 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 ) + -- 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 + -- 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 ) - -- Get the relative direction between the player's vehicle and the hit vehicle - local dir = UTIL:GetEntityRelativeDirection( ownH, tarH ) + -- Get the relative direction between the player's vehicle and the hit vehicle + 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 - local plate = GetVehicleNumberPlateText( veh ) + -- 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 + local plate = GetVehicleNumberPlateText( veh ) - -- Get the licence plate index from the vehicle - local index = GetVehicleNumberPlateTextIndex( veh ) + -- 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 - -- Set the plate for the current reader - self:SetPlate( cam, plate ) + -- 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 + -- Set the plate for the current reader + self:SetPlate( cam, plate ) - -- Set the plate index for the current reader - self:SetIndex( cam, index ) + -- Set the plate index for the current reader + self:SetIndex( cam, index ) - -- Automatically lock the plate if the scanned plate matches the BOLO - if ( plate == self:GetBoloPlate() ) then - self:LockCam( cam, false, true ) + -- Automatically lock the plate if the scanned plate matches the BOLO + if ( plate == self:GetBoloPlate() ) then + self:LockCam( cam, false, true ) - SendNUIMessage( { _type = "audio", name = "plate_hit", vol = RADAR:GetSettingValue( "plateAudio" ) } ) - end + -- SendNUIMessage( { _type = "audio", name = "plate_hit", vol = RADAR:GetSettingValue( "plateAudio" ) } ) + end - -- Send the plate information to the NUI side to update the UI - SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) + -- Send the plate information to the NUI side to update the UI + SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) - -- Trigger the event so developers can hook into the scanner - TriggerEvent( "wk:onPlateScanned", cam, plate, index ) - end - end - end - end - end + -- 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 -- Main thread Citizen.CreateThread( function() - while ( true ) do - -- Run the main plate reader function - READER:Main() + while ( true ) do + -- Run the main plate reader function + READER:Main() - -- Wait half a second - Citizen.Wait( 500 ) - end + -- Wait half a second + Citizen.Wait( 500 ) + end end ) -- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not @@ -244,11 +279,11 @@ end 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 ) \ No newline at end of file diff --git a/cl_radar.lua b/cl_radar.lua index b415ec7..564a1be 100644 --- a/cl_radar.lua +++ b/cl_radar.lua @@ -1,9 +1,34 @@ ---[[---------------------------------------------------------------------------------- +--[[--------------------------------------------------------------------------------------- Wraith ARS 2X Created by WolfKnight + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + + MIT License -----------------------------------------------------------------------------------]]-- + Copyright (c) 2020 WolfKnight + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +---------------------------------------------------------------------------------------]]-- -- Cache some of the main Lua functions and libraries local next = next @@ -23,7 +48,7 @@ Citizen.SetTimeout( 1000, function() local name = GetCurrentResourceName() -- Print a little message in the client's console - print( "WK_WARS2X: Sending resource name (" .. name .. ") to JavaScript side." ) + print( "[wk_wars2x]: Sending resource name (" .. name .. ") to JavaScript side." ) -- Send a message through the NUI system to the JavaScript file to give the name of the resource SendNUIMessage( { _type = "updatePathName", pathName = name } ) @@ -51,6 +76,12 @@ AddEventHandler( "wk:loadUiData", function( data ) SendNUIMessage( { _type = "loadUiSettings", data = data } ) end ) +RegisterNetEvent( "wk:setUiDefaults" ) +AddEventHandler( "wk:setUiDefaults", function() + SendNUIMessage( { _type = "setUiDefaults", data = CONFIG.uiDefaults } ) +end ) + + --[[---------------------------------------------------------------------------------- Player info variables ----------------------------------------------------------------------------------]]-- @@ -116,10 +147,10 @@ RADAR.vars = ["beep"] = CONFIG.menuDefaults["beep"], -- The volume of the verbal lock confirmation - ["voice"] = CONFIG.menuDefaults["voice"], - - -- The volume of the plate reader audio - ["plateAudio"] = CONFIG.menuDefaults["plateAudio"], + ["voice"] = CONFIG.menuDefaults["voice"], + + -- The volume of the plate reader audio + ["plateAudio"] = CONFIG.menuDefaults["plateAudio"], -- The speed unit used in conversions ["speedType"] = CONFIG.menuDefaults["speedType"] @@ -134,8 +165,8 @@ RADAR.vars = { displayText = { "¦SL", "SEn" }, optionsText = { "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "same" }, { displayText = { "¦OP", "SEn" }, optionsText = { "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "opp" }, { displayText = { "bEE", "P¦¦" }, optionsText = { "Off", "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "beep" }, - { displayText = { "VOI", "CE¦" }, optionsText = { "Off", "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "voice" }, - { displayText = { "PLt", "AUd" }, optionsText = { "Off", "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "plateAudio" }, + { displayText = { "VOI", "CE¦" }, optionsText = { "Off", "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "voice" }, + { displayText = { "PLt", "AUd" }, optionsText = { "Off", "¦1¦", "¦2¦", "¦3¦", "¦4¦", "¦5¦" }, options = { 0.0, 0.2, 0.4, 0.6, 0.8, 1.0 }, optionIndex = -1, settingText = "plateAudio" }, { displayText = { "Uni", "tS¦" }, optionsText = { "USA", "INT" }, options = { "mph", "kmh" }, optionIndex = -1, settingText = "speedType" } }, @@ -158,6 +189,7 @@ RADAR.vars = 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 @@ -204,11 +236,11 @@ RADAR.vars = threadWaitTime = 500, -- Key lock, when true, prevents any of the radar's key events from working, like the ELS key lock - keyLock = false, - - -- Full keyboard, when true, the keybinds for the radar will be set to the keys on the numpad, when false, the - -- keybinds for the radar will be set to the number keys above WASD - fullKeyboard = true + keyLock = false, + + -- Full keyboard, when true, the keybinds for the radar will be set to the keys on the numpad, when false, the + -- keybinds for the radar will be set to the number keys above WASD + fullKeyboard = true } -- Speed conversion values @@ -377,28 +409,6 @@ function RADAR:OpenRemote() end end --- 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() - -- Iterate through each of the internal settings - 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 - -- 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 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 - t.optionIndex = oi - end - end - end - end - end -end - -- Returns if the fast limit option should be available for the radar function RADAR:IsFastLimitAllowed() return CONFIG.allow_fast_limit @@ -462,28 +472,28 @@ end -- Toggles between the full and small keybinds function RADAR:ToggleFullKeyboard() - -- Check the player state is valid - if ( PLY:VehicleStateValid() ) then - -- Toggle the full keyboard state - self.vars.fullKeyboard = not self.vars.fullKeyboard + -- Check the player state is valid + if ( PLY:VehicleStateValid() ) then + -- Toggle the full keyboard state + self.vars.fullKeyboard = not self.vars.fullKeyboard - -- Tell the NUI side to display the keybind message - SendNUIMessage( { _type = "displayKeybindChange", state = self:GetFullKeyboardState() } ) - end + -- Tell the NUI side to display the keybind message + SendNUIMessage( { _type = "displayKeybindChange", state = self:GetFullKeyboardState() } ) + end end -- Returns the full keyboard state function RADAR:GetFullKeyboardState() - return self.vars.fullKeyboard + return self.vars.fullKeyboard end -- Returns which keybind set to use function RADAR:GetKeybindType() - if ( self:GetFullKeyboardState() ) then - return "full" - else - return "small" - end + if ( self:GetFullKeyboardState() ) then + return "full" + else + return "small" + end end @@ -594,6 +604,28 @@ function RADAR:SendMenuUpdate() SendNUIMessage( { _type = "menu", text = self:GetMenuOptionDisplayText(), option = self:GetMenuOptionText() } ) end +-- 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() + -- Iterate through each of the internal settings + 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 + -- 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 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 + t.optionIndex = oi + end + end + end + end + end +end + --[[---------------------------------------------------------------------------------- Radar basics functions @@ -991,19 +1023,19 @@ function RADAR:SetAntennaSpeedLock( ant, speed, dir, lockType ) 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 - SendNUIMessage( { _type = "lockAudio", ant = ant, dir = dir, vol = self:GetSettingValue( "voice" ) } ) - - -- Great Scott! - if ( speed == "¦88" and self:GetSettingValue( "speedType" ) == "mph" ) then - math.randomseed( GetGameTimer() ) + SendNUIMessage( { _type = "lockAudio", ant = ant, dir = dir, vol = self:GetSettingValue( "voice" ) } ) + + -- Great Scott! + if ( speed == "¦88" and self:GetSettingValue( "speedType" ) == "mph" ) then + math.randomseed( GetGameTimer() ) - local chance = math.random() - - -- 15% chance - if ( chance <= 0.15 ) then - SendNUIMessage( { _type = "audio", name = "speed_alert", vol = self:GetSettingValue( "beep" ) } ) - end - end + local chance = math.random() + + -- 15% chance + if ( chance <= 0.15 ) then + SendNUIMessage( { _type = "audio", name = "speed_alert", vol = self:GetSettingValue( "beep" ) } ) + end + end end end @@ -1110,28 +1142,6 @@ function RADAR:InsertCapturedVehicleData( t, rt ) end end ---[[ - These need to be changed so a ray type can be set too, otherwise in its current state, messes up vehicle - detection. - --- Sets the given value to true in the temp vehicles table, it is a test system used to reduce ray traces --- on vehicles that have already been hit by another trace. Currently not implemented fully, as it doesn't --- check for ray traces of different types, e.g. same or opp. -function RADAR:HasVehicleAlreadyBeenHit( key ) - return self.vars.tempVehicleIDs[key] -end - --- Returns if a vehicle has already been hit by a ray trace -function RADAR:SetVehicleHasBeenHit( key ) - self.vars.tempVehicleIDs[key] = true -end - --- Resets the temporary vehicle ids table -function RADAR:ResetTempVehicleIDs() - self.vars.tempVehicleIDs = {} -end -]] - --[[---------------------------------------------------------------------------------- Radar dynamic sphere radius functions @@ -1351,74 +1361,74 @@ end ) -- Runs when the user presses any of the antenna mode buttons on the remote RegisterNUICallback( "setAntennaMode", function( data ) - -- 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 - -- Set the internal menu state to be closed (false) - RADAR:SetMenuState( false ) - - -- Send a setting update to the NUI side - RADAR:SendSettingUpdate() - - -- Play a menu done beep - SendNUIMessage( { _type = "audio", name = "done", vol = RADAR:GetSettingValue( "beep" ) } ) - 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 - SendNUIMessage( { _type = "antennaMode", ant = data.value, mode = tonumber( data.mode ) } ) - - -- Play a beep - SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) - end ) - end - end + -- 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 + -- Set the internal menu state to be closed (false) + RADAR:SetMenuState( false ) + + -- Send a setting update to the NUI side + RADAR:SendSettingUpdate() + + -- Play a menu done beep + SendNUIMessage( { _type = "audio", name = "done", vol = RADAR:GetSettingValue( "beep" ) } ) + 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 + SendNUIMessage( { _type = "antennaMode", ant = data.value, mode = tonumber( data.mode ) } ) + + -- Play a beep + SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) + end ) + end + end end ) -- Runs when the user presses either of the XMIT/HOLD buttons on the remote RegisterNUICallback( "toggleAntenna", function( data ) - -- 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 - -- Change the menu option based on which button is pressed - RADAR:ChangeMenuOption( data.value ) - - -- 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" ) } ) - end ) - end - end + -- 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 + -- Change the menu option based on which button is pressed + RADAR:ChangeMenuOption( data.value ) + + -- 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" ) } ) + end ) + end + end end ) -- Runs when the user presses the menu button on the remote control RegisterNUICallback( "menu", function() - -- Only run the codw if the radar has power and is not powering up - 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 - -- As the menu is already open, we then iterate to the next option in the settings list - RADAR:ChangeMenuIndex() - 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 + -- Only run the codw if the radar has power and is not powering up + 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 + -- As the menu is already open, we then iterate to the next option in the settings list + RADAR:ChangeMenuIndex() + 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 - -- Play the standard audio beep - SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) - end + -- Play the standard audio beep + SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) + end end ) -- Runs when the JavaScript side sends the UI data for saving @@ -1600,8 +1610,6 @@ function RADAR:Main() -- Send the update to the NUI side SendNUIMessage( { _type = "update", speed = data.patrolSpeed, antennas = data.antennas } ) - - -- self:ResetTempVehicleIDs() end end @@ -1614,10 +1622,10 @@ Citizen.CreateThread( function() 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() + 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 @@ -1684,8 +1692,8 @@ end ) function RunControlManager() -- Make sure only the keyboard works if ( IsInputDisabled( 0 ) ) then - if ( not RADAR:GetKeyLockState() ) then - local keyType = RADAR:GetKeybindType() + if ( not RADAR:GetKeyLockState() ) then + local keyType = RADAR:GetKeybindType() -- Opens the remote control if ( IsDisabledControlJustPressed( 1, CONFIG.keys.remote_control ) ) then @@ -1716,18 +1724,13 @@ function RunControlManager() -- Toggles the key lock state if ( IsDisabledControlJustPressed( 1, CONFIG.keys.key_lock ) ) then RADAR:ToggleKeyLock() - end - - -- Toggles between the keybind types - if ( IsDisabledControlJustPressed( 1, CONFIG.keys.switch_keys ) ) then + end + + -- Toggles between the keybind types + if ( IsDisabledControlJustPressed( 1, CONFIG.keys.switch_keys ) ) then RADAR:ToggleFullKeyboard() - end + end end - - -- Shortcut to restart the resource - --[[ if ( IsDisabledControlJustPressed( 1, 167 ) ) then - ExecuteCommand( "restart wk_wars2x" ) - end ]] end -- Control manager diff --git a/cl_utils.lua b/cl_utils.lua index e84e2f5..a59af59 100644 --- a/cl_utils.lua +++ b/cl_utils.lua @@ -1,9 +1,34 @@ ---[[----------------------------------------------------------------------- +--[[--------------------------------------------------------------------------------------- Wraith ARS 2X Created by WolfKnight + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + + MIT License ------------------------------------------------------------------------]]-- + Copyright (c) 2020 WolfKnight + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +---------------------------------------------------------------------------------------]]-- UTIL = {} diff --git a/config.lua b/config.lua index 757173f..e930ef5 100644 --- a/config.lua +++ b/config.lua @@ -1,9 +1,34 @@ ---[[------------------------------------------------------------------------ +--[[--------------------------------------------------------------------------------------- Wraith ARS 2X Created by WolfKnight + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + + MIT License -------------------------------------------------------------------------]]-- + Copyright (c) 2020 WolfKnight + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +---------------------------------------------------------------------------------------]]-- -- Do not touch this CONFIG = {} @@ -16,83 +41,100 @@ CONFIG.allow_fast_limit = true -- Sets all of the controls CONFIG.keys = { - -- Remote control key - -- The default key to open the remote control is 166 (F5 - INPUT_SELECT_CHARACTER_MICHAEL) - remote_control = 166, + -- Remote control key + -- The default key to open the remote control is 166 (F5 - INPUT_SELECT_CHARACTER_MICHAEL) + remote_control = 166, - -- Radar key lock key - -- The default key to enable/disable the radar key lock is 182 (L - INPUT_CELLPHONE_CAMERA_FOCUS_LOCK) - key_lock = 182, + -- Radar key lock key + -- The default key to enable/disable the radar key lock is 182 (L - INPUT_CELLPHONE_CAMERA_FOCUS_LOCK) + key_lock = 182, - -- Radar keybinds switch - -- The default to key to switch the bind set is (K - INPUT_REPLAY_SHOWHOTKEY) - switch_keys = 311, + -- Radar keybinds switch + -- The default to key to switch the bind set is (K - INPUT_REPLAY_SHOWHOTKEY) + switch_keys = 311, - -- Keys for a full size keyboard - [ "full" ] = { - -- Radar front antenna lock/unlock Key - -- The default full keyboard key to lock/unlock the front antenna is 111 (Numpad 8 - INPUT_VEH_FLY_PITCH_UP_ONLY) - front_lock = 111, + -- Keys for a full size keyboard + [ "full" ] = { + -- Radar front antenna lock/unlock Key + -- The default full keyboard key to lock/unlock the front antenna is 111 (Numpad 8 - INPUT_VEH_FLY_PITCH_UP_ONLY) + front_lock = 111, - -- Radar rear antenna lock/unlock Key - -- The default full keyboard key to lock/unlock the rear antenna is 112 (Numpad 5 - INPUT_VEH_FLY_PITCH_DOWN_ONLY) - rear_lock = 112, + -- Radar rear antenna lock/unlock Key + -- The default full keyboard key to lock/unlock the rear antenna is 112 (Numpad 5 - INPUT_VEH_FLY_PITCH_DOWN_ONLY) + rear_lock = 112, - -- Plate reader front lock/unlock Key - -- The default full keyboard key to lock/unlock the front plate reader is 118 (Numpad 9 - INPUT_VEH_FLY_SELECT_TARGET_RIGHT) - plate_front_lock = 118, + -- Plate reader front lock/unlock Key + -- The default full keyboard key to lock/unlock the front plate reader is 118 (Numpad 9 - INPUT_VEH_FLY_SELECT_TARGET_RIGHT) + plate_front_lock = 118, - -- Plate reader rear lock/unlock Key - -- The default full keyboard key to lock/unlock the rear plate reader is 109 (Numpad 6 - INPUT_VEH_FLY_ROLL_RIGHT_ONLY) - plate_rear_lock = 109 - }, + -- Plate reader rear lock/unlock Key + -- The default full keyboard key to lock/unlock the rear plate reader is 109 (Numpad 6 - INPUT_VEH_FLY_ROLL_RIGHT_ONLY) + plate_rear_lock = 109 + }, - -- Keys for smaller keyboards - [ "small" ] = { - -- Radar front antenna lock/unlock Key - -- The default small keyboard key to lock/unlock the front antenna is 157 (1 - INPUT_SELECT_WEAPON_UNARMED) - front_lock = 157, + -- Keys for smaller keyboards + [ "small" ] = { + -- Radar front antenna lock/unlock Key + -- The default small keyboard key to lock/unlock the front antenna is 157 (1 - INPUT_SELECT_WEAPON_UNARMED) + front_lock = 157, - -- Radar rear antenna lock/unlock Key - -- The default small keyboard key to lock/unlock the rear antenna is 158 (2 - INPUT_SELECT_WEAPON_MELEE) - rear_lock = 158, + -- Radar rear antenna lock/unlock Key + -- The default small keyboard key to lock/unlock the rear antenna is 158 (2 - INPUT_SELECT_WEAPON_MELEE) + rear_lock = 158, - -- Plate reader front lock/unlock Key - -- The default small keyboard key to lock/unlock the front plate reader is 160 (3 - INPUT_SELECT_WEAPON_SHOTGUN) - plate_front_lock = 160, + -- Plate reader front lock/unlock Key + -- The default small keyboard key to lock/unlock the front plate reader is 160 (3 - INPUT_SELECT_WEAPON_SHOTGUN) + plate_front_lock = 160, - -- Plate reader rear lock/unlock Key - -- The default small keyboard key to lock/unlock the rear plate reader is 164 (4 - INPUT_SELECT_WEAPON_HEAVY) - plate_rear_lock = 164 - } + -- Plate reader rear lock/unlock Key + -- The default small keyboard key to lock/unlock the rear plate reader is 164 (4 - INPUT_SELECT_WEAPON_HEAVY) + plate_rear_lock = 164 + } } -- 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 = { - -- Should the system calculate and display faster targets - -- Options: true or false - ["fastDisplay"] = true, + -- Should the system calculate and display faster targets + -- Options: true or false + ["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, + -- 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, - -- 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 - ["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 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 + ["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 speed unit used in conversions - -- Options: mph or kmh - ["speedType"] = "mph" + -- The speed unit used in conversions + -- Options: mph or kmh + ["speedType"] = "mph" +} + +-- Here you can change the default scale of the UI elements, as well as the safezone size +CONFIG.uiDefaults = +{ + -- The default scale of the UI elements. + -- Options: 0.25 - 2.5 + scale = + { + radar = 1.5, + remote = 1.5, + plateReader = 1.5 + }, + + -- The safezone size, must be a multiple of 5. + -- Options: 0 - 100 + safezone = 20 } \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index 4bc2aa4..fb189b8 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -1,9 +1,34 @@ ---[[----------------------------------------------------------------------- +--[[--------------------------------------------------------------------------------------- Wraith ARS 2X Created by WolfKnight + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + + MIT License ------------------------------------------------------------------------]]-- + Copyright (c) 2020 WolfKnight + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +---------------------------------------------------------------------------------------]]-- -- Define the FX Server version and game type fx_version "adamant" @@ -13,19 +38,19 @@ game "gta5" name "Wraith ARS 2X" description "Police radar and plate reader system for FiveM" author "WolfKnight" -version "pre-release" +version "1.0.0" -- Include the files files { - "nui/radar.html", - "nui/radar.css", - "nui/jquery-3.4.1.min.js", - "nui/radar.js", - "nui/images/*.png", - "nui/images/plates/*.png", - "nui/fonts/*.ttf", - "nui/fonts/Segment7Standard.otf", - "nui/sounds/*.ogg" + "nui/radar.html", + "nui/radar.css", + "nui/jquery-3.4.1.min.js", + "nui/radar.js", + "nui/images/*.png", + "nui/images/plates/*.png", + "nui/fonts/*.ttf", + "nui/fonts/Segment7Standard.otf", + "nui/sounds/*.ogg" } -- Set the NUI page @@ -34,6 +59,8 @@ ui_page "nui/radar.html" -- Run the server scripts server_script "sv_version_check.lua" server_script "sv_saving.lua" +server_script "sv_exports.lua" +server_export "TogglePlateLock" -- Run the client scripts client_script "config.lua" diff --git a/nui/radar.css b/nui/radar.css index e92e4c7..b2520e1 100644 --- a/nui/radar.css +++ b/nui/radar.css @@ -1,3 +1,35 @@ +/*----------------------------------------------------------------------------------------- + + Wraith ARS 2X + Created by WolfKnight + + For discussions, information on future updates, and more, join + my Discord: https://discord.gg/fD4e6WD + + MIT License + + Copyright (c) 2020 WolfKnight + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +-----------------------------------------------------------------------------------------*/ + @font-face { font-family: "Seg-7"; src: url( "fonts/Segment7Standard.otf" ); @@ -14,30 +46,30 @@ } @font-face { - font-family: "Plate-Font"; - src: url( "fonts/plate-font.ttf" ); + font-family: "Plate-Font"; + src: url( "fonts/plate-font.ttf" ); } @font-face { - font-family: "Plate-Font-Hilite"; - src: url( "fonts/plate-font-hilite.ttf" ); + font-family: "Plate-Font-Hilite"; + src: url( "fonts/plate-font-hilite.ttf" ); } @font-face { - font-family: "Plate-Font-Lolite"; - src: url( "fonts/plate-font-lolite.ttf" ); + font-family: "Plate-Font-Lolite"; + src: url( "fonts/plate-font-lolite.ttf" ); } @font-face { - font-family: "Plate-Font-Shadow"; - src: url( "fonts/plate-font-Shadow.ttf" ); + font-family: "Plate-Font-Shadow"; + src: url( "fonts/plate-font-Shadow.ttf" ); } * { font-family: 'Heebo', Verdana, Geneva, Tahoma, sans-serif; font-size: 13px; - box-sizing: border-box; - user-select: none; + box-sizing: border-box; + user-select: none; } body { @@ -52,18 +84,18 @@ button:focus { outline: none; } height: 230px; position: absolute; - margin: auto; - - top: calc( ( 100% - 10px ) - 230px ); - left: calc( ( 100% - 10px ) - 715px ); + margin: auto; + + top: calc( ( 100% - 10px ) - 230px ); + left: calc( ( 100% - 10px ) - 715px ); background-image: url( "images/frame.png" ); /* Settings for scaling */ transform: scale( 1.0 ); - transform-origin: 0 0; - - transition: transform 0.5s; + transform-origin: 0 0; + + transition: transform 0.5s; z-index: 2; } @@ -117,14 +149,14 @@ button:focus { outline: none; } transform: translateX( -1px ); background-image: url( "images/bg_right.png" ); background-repeat: no-repeat; - } - + } + .plate_blue { - color: rgb(0, 0, 163); + color: rgb(0, 0, 163); } .plate_yellow { - color: rgb(255, 255, 0); + color: rgb(255, 255, 0); } .arrow { @@ -247,7 +279,10 @@ button:focus { outline: none; } border: 2px solid rgb( 0, 0, 0 ); margin: auto 0; + + /* If you would like your strong target window to be solid rather than have a gradient, swap the comment for the 2 lines below */ background-color: rgb( 61, 18, 0 ); + /* background: linear-gradient( to bottom, rgb( 52, 13, 1 ), rgb( 57, 16, 0 ) 40%, rgb( 65, 25, 4 ) 85% ); */ } #radar .speeds_container .display p { grid-row-start: 1; @@ -266,7 +301,10 @@ button:focus { outline: none; } #radar .speeds_container .fast { height: 60px; + + /* If you would like your fast target window to be solid rather than have a gradient, swap the comment for the 2 lines below */ background-color: rgb( 50, 0, 0 ); + /* background: linear-gradient( to bottom, rgb( 40, 0, 0 ), rgb( 45, 0, 0 ) 40%, rgb( 50, 0, 0 ) 85% ); */ } #radar .speeds_container .fast p { font-size: 60px; @@ -326,6 +364,7 @@ button:focus { outline: none; } } #radar .patrol_and_logo_container .display { + /* If you would like your patrol speed window to be solid rather than have a gradient, swap the comment for the 2 lines below */ background-color: rgb( 0, 57, 35 ); /* background: linear-gradient( to bottom, rgb( 0, 40, 29 ), rgb( 0, 46, 32 ) 40%, rgb( 1, 64, 27 ) 85% ); */ } @@ -372,8 +411,8 @@ button:focus { outline: none; } height: 800px; position: absolute; - top: calc( 50% - ( 800px / 2 ) ); - left: calc( 50% - ( 315px / 2 ) ); + top: calc( 50% - ( 800px / 2 ) ); + left: calc( 50% - ( 315px / 2 ) ); margin: auto; padding: 65px 30px 50px 30px; @@ -383,15 +422,15 @@ button:focus { outline: none; } align-items: center; color: white; - background-image: url( "images/rc_bg.png" ); - - transition: transform 0.5s; - - /* Settings for scaling */ + background-image: url( "images/rc_bg.png" ); + + transition: transform 0.5s; + + /* Settings for scaling */ transform: scale( 1.0 ); transform-origin: 0 0; - z-index: 3; + z-index: 3; } /* Button template classes */ #rc button { @@ -567,8 +606,8 @@ button:focus { outline: none; } } #rc .plate_reader_and_help_container .help { - padding: 0 10px; - font-size: 15px; + padding: 0 10px; + font-size: 15px; } #rc .light { @@ -587,250 +626,250 @@ button:focus { outline: none; } #rc .blue { background-color: rgb( 84, 210, 255 ); - } - + } + #plateReaderFrame { - width: 500px; - height: 200px; + width: 500px; + height: 200px; - position: absolute; - margin: auto; + position: absolute; + margin: auto; - top: calc( 50% - ( 200px / 2 ) ); - left: calc( 50% - ( 500px / 2 ) ); + top: calc( 50% - ( 200px / 2 ) ); + left: calc( 50% - ( 500px / 2 ) ); - background-image: url( "images/pr_frame.png" ); + background-image: url( "images/pr_frame.png" ); - transition: transform 0.5s; + transition: transform 0.5s; - /* Settings for scaling */ + /* Settings for scaling */ transform: scale( 1.0 ); transform-origin: 0 0; - z-index: 1; + z-index: 1; } - #plateReaderFrame .frame_border { - width: 465px; - height: 175px; + #plateReaderFrame .frame_border { + width: 465px; + height: 175px; - position: absolute; - margin: auto; - top: 0; - right: 0; - bottom: 0; - left: 0; + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; - background-color: rgb( 20, 22, 18 ); + background-color: rgb( 20, 22, 18 ); - border-radius: 5px; - } + border-radius: 5px; + } #plateReader { - width: 460px; - height: 170px; - - position: absolute; - margin: auto; - top: 0; - right: 0; - bottom: 0; - left: 0; - - background-image: url( "images/pr_bg.png" ); - - box-shadow: inset 0px 20px 20px -15px rgba( 0, 0, 0, 0.4 ); - - display: grid; - grid-template-rows: 30px 1fr 30px; - align-content: center; -} - #plateReader .labels { - display: grid; - grid-template-columns: 1fr 1fr; - align-content: center; - } - #plateReader .labels .title { - color: rgb( 255, 255, 255 ); - } - - #plateReader .labels p { - margin: 0; - text-align: center; - font-size: 18px; - } - - #plateReader .plates { - width: 100%; - height: 100%; - - display: grid; - grid-template-columns: 1fr 1fr; - align-content: center; - justify-items: center; - } - #plateReader .plates .plate_container { - width: 90%; - height: 100%; - - display: grid; - grid-template-columns: 1fr; - justify-content: center; - } - #plateReader .plates .plate_container .plate { - display: block; - max-width: 100%; - height: auto; - grid-column: 1; - grid-row: 1; - } - - #plateReader .plates .plate_container .text_container { - grid-column: 1; - grid-row: 1; - - display: grid; - grid-template-columns: 1fr; - justify-content: center; - } - #plateReader .plates .plate_container .text_container p { - display: block; - font-family: "Plate-Font"; - font-size: 58px; - text-align: center; - letter-spacing: -3px; - padding-top: 5px; - margin: 0; - grid-column: 1; - grid-row: 1; - } - - #plateReader .plates .plate_container .text_container .hilite { - font-family: "Plate-Font-Hilite"; - color: rgb( 93, 65, 255 ); - } - - #plateReader .plates .plate_container .text_container .lolite { - font-family: "Plate-Font-Lolite"; - color: rgb( 255, 255, 255 ); - } - - #plateReader .plates .plate_container .text_container .shadow { - font-family: "Plate-Font-Shadow"; - color: rgb( 100, 100, 100 ); - } - -.plate_hit { - animation: plate_flash linear 0.6s infinite; -} - -@keyframes plate_flash { - 0% { opacity: 1.0; } - 50% { opacity: 0.0; } - 100% { opacity: 1.0; } -} - -#plateReaderBox { - width: 225px; - height: 300px; - - position: absolute; - margin: auto; - top: 0; - right: 0; - bottom: 0; - left: 0; - - background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); - border: 3px solid rgb( 0, 0, 0 ); - - z-index: 4; -} - #plateReaderBox .title { - text-align: center; - font-size: 20px; - padding: 5px 0; - margin: 0 auto; - color: rgb( 255, 255, 255 ); - background-color: rgb( 20, 22, 18 ); - } - - #plateReaderBox .header { - width: 100%; - } - - #plateReaderBox .container { - width: 100%; - height: 200px; - - display: grid; - grid-template-rows: 60px 70px 60px; - align-items: center; - justify-items: center; - } - #plateReaderBox .container .btn { - width: 140px; - height: 35px; - border-radius: 10px; - font-size: 16px; - border: none; - } - #plateReaderBox .container .btn:hover { - background-color: rgb( 255, 255, 255 ); - } - - #plateReaderBox .container .btn:active { - background-color: rgb( 190, 190, 190 ); - padding: 0; - } - - #plateReaderBox .container .plate_input { - width: 75%; - height: 50px; - font-family: "Plate-Font"; - text-align: center; - font-size: 38px; - text-transform: uppercase; - padding: 0; - padding-bottom: 15px; - margin-bottom: -15px; - } - - #plateReaderBox .close { - width: 80px; - height: 20px; - - position: absolute; - left: 0; - right: 0; - bottom: 10px; - margin: auto; - - border-radius: 10px; - border: none; - background-color: rgb( 225, 225, 225 ); - } - #plateReaderBox .close:hover { - background-color: rgb( 255, 255, 255 ); - } - - #plateReaderBox .close:active { - background-color: rgb( 190, 190, 190 ); - padding: 0; - } - -#uiSettingsBox { - width: 250px; - height: 375px; + width: 460px; + height: 170px; position: absolute; margin: auto; top: 0; right: 0; bottom: 0; - left: 0; - - background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); - border: 3px solid rgb( 0, 0, 0 ); + left: 0; + + background-image: url( "images/pr_bg.png" ); + + box-shadow: inset 0px 20px 20px -15px rgba( 0, 0, 0, 0.4 ); + + display: grid; + grid-template-rows: 30px 1fr 30px; + align-content: center; +} + #plateReader .labels { + display: grid; + grid-template-columns: 1fr 1fr; + align-content: center; + } + #plateReader .labels .title { + color: rgb( 255, 255, 255 ); + } + + #plateReader .labels p { + margin: 0; + text-align: center; + font-size: 18px; + } + + #plateReader .plates { + width: 100%; + height: 100%; + + display: grid; + grid-template-columns: 1fr 1fr; + align-content: center; + justify-items: center; + } + #plateReader .plates .plate_container { + width: 90%; + height: 100%; + + display: grid; + grid-template-columns: 1fr; + justify-content: center; + } + #plateReader .plates .plate_container .plate { + display: block; + max-width: 100%; + height: auto; + grid-column: 1; + grid-row: 1; + } + + #plateReader .plates .plate_container .text_container { + grid-column: 1; + grid-row: 1; + + display: grid; + grid-template-columns: 1fr; + justify-content: center; + } + #plateReader .plates .plate_container .text_container p { + display: block; + font-family: "Plate-Font"; + font-size: 58px; + text-align: center; + letter-spacing: -3px; + padding-top: 5px; + margin: 0; + grid-column: 1; + grid-row: 1; + } + + #plateReader .plates .plate_container .text_container .hilite { + font-family: "Plate-Font-Hilite"; + color: rgb( 93, 65, 255 ); + } + + #plateReader .plates .plate_container .text_container .lolite { + font-family: "Plate-Font-Lolite"; + color: rgb( 255, 255, 255 ); + } + + #plateReader .plates .plate_container .text_container .shadow { + font-family: "Plate-Font-Shadow"; + color: rgb( 100, 100, 100 ); + } + +.plate_hit { + animation: plate_flash linear 0.6s infinite; +} + +@keyframes plate_flash { + 0% { opacity: 1.0; } + 50% { opacity: 0.0; } + 100% { opacity: 1.0; } +} + +#plateReaderBox { + width: 225px; + height: 300px; + + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + + background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); + border: 3px solid rgb( 0, 0, 0 ); + + z-index: 4; +} + #plateReaderBox .title { + text-align: center; + font-size: 20px; + padding: 5px 0; + margin: 0 auto; + color: rgb( 255, 255, 255 ); + background-color: rgb( 20, 22, 18 ); + } + + #plateReaderBox .header { + width: 100%; + } + + #plateReaderBox .container { + width: 100%; + height: 200px; + + display: grid; + grid-template-rows: 60px 70px 60px; + align-items: center; + justify-items: center; + } + #plateReaderBox .container .btn { + width: 140px; + height: 35px; + border-radius: 10px; + font-size: 16px; + border: none; + } + #plateReaderBox .container .btn:hover { + background-color: rgb( 255, 255, 255 ); + } + + #plateReaderBox .container .btn:active { + background-color: rgb( 190, 190, 190 ); + padding: 0; + } + + #plateReaderBox .container .plate_input { + width: 75%; + height: 50px; + font-family: "Plate-Font"; + text-align: center; + font-size: 38px; + text-transform: uppercase; + padding: 0; + padding-bottom: 15px; + margin-bottom: -15px; + } + + #plateReaderBox .close { + width: 80px; + height: 20px; + + position: absolute; + left: 0; + right: 0; + bottom: 10px; + margin: auto; + + border-radius: 10px; + border: none; + background-color: rgb( 225, 225, 225 ); + } + #plateReaderBox .close:hover { + background-color: rgb( 255, 255, 255 ); + } + + #plateReaderBox .close:active { + background-color: rgb( 190, 190, 190 ); + padding: 0; + } + +#uiSettingsBox { + width: 250px; + height: 400px; + + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + + background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); + border: 3px solid rgb( 0, 0, 0 ); z-index: 3; } @@ -845,20 +884,20 @@ button:focus { outline: none; } #uiSettingsBox .header { width: 100%; - } - - #uiSettingsBox .scaling_container { - height: 225px; - display: grid; - grid-template-rows: 1fr 1fr 1fr; - } + } + + #uiSettingsBox .scaling_container { + height: 225px; + display: grid; + grid-template-rows: 1fr 1fr 1fr; + } #uiSettingsBox .scaling { height: 70px; - - display: grid; - grid-template-columns: 1fr 2fr 1fr; - place-items: center center; + + display: grid; + grid-template-columns: 1fr 2fr 1fr; + place-items: center center; } #uiSettingsBox .scaling p { font-size: 18px; @@ -890,60 +929,60 @@ button:focus { outline: none; } #uiSettingsBox .scaling .plus { clip-path: polygon( 0 35%, 35% 35%, 35% 0, 65% 0, 65% 35%, 100% 35%, 100% 65%, 65% 65%, 65% 100%, 35% 100%, 35% 65%, 0 65% ); - } - - #uiSettingsBox .safezone_container { - width: 85%; - margin: 0 auto; - } - #uiSettingsBox .safezone_container p, - #uiSettingsBox .safezone_container span { - font-size: 18px; + } + + #uiSettingsBox .safezone_container { + width: 85%; + margin: 0 auto; + } + #uiSettingsBox .safezone_container p, + #uiSettingsBox .safezone_container span { + font-size: 18px; margin: 0 auto; text-align: center; color: rgb( 255, 255, 255 ); - } + } - #uiSettingsBox .safezone_container .slider { - width: 100%; - height: 10px; - margin: 10px 0; + #uiSettingsBox .safezone_container .slider { + width: 100%; + height: 10px; + margin: 10px 0; - border-radius: 5px; + border-radius: 5px; - -webkit-appearance: none; + -webkit-appearance: none; - background-color: rgb( 180, 180, 180 ); - } + background-color: rgb( 180, 180, 180 ); + } - #uiSettingsBox .safezone_container .slider:focus { - outline: none; - } - #uiSettingsBox .safezone_container .slider::-webkit-slider-thumb { - -webkit-appearance: none; - appearance: none; - width: 15px; - height: 25px; - background: rgb( 84, 210, 255 ); - cursor: pointer; - } - - #uiSettingsBox .safezone_container .slider::-moz-range-thumb { - width: 15px; - height: 25px; - background: rgb( 84, 210, 255 ); - cursor: pointer; - } + #uiSettingsBox .safezone_container .slider:focus { + outline: none; + } + #uiSettingsBox .safezone_container .slider::-webkit-slider-thumb { + -webkit-appearance: none; + appearance: none; + width: 15px; + height: 25px; + background: rgb( 84, 210, 255 ); + cursor: pointer; + } + + #uiSettingsBox .safezone_container .slider::-moz-range-thumb { + width: 15px; + height: 25px; + background: rgb( 84, 210, 255 ); + cursor: pointer; + } #uiSettingsBox .close { width: 80px; height: 20px; - position: absolute; - left: 0; - right: 0; - bottom: 30px; - margin: auto; + position: absolute; + left: 0; + right: 0; + bottom: 30px; + margin: auto; border-radius: 10px; border: none; @@ -956,61 +995,61 @@ button:focus { outline: none; } #uiSettingsBox .close:active { background-color: rgb( 190, 190, 190 ); padding: 0; - } + } #keyLockLabel, #keyBindsLabel { - position: absolute; - left: 0; - right: 0; - bottom: 350px; + position: absolute; + left: 0; + right: 0; + bottom: 350px; - text-align: center; - font-size: 30px; + text-align: center; + font-size: 30px; - color: rgb(255, 255, 255); - text-shadow: 3px 2px 5px rgb( 0, 0, 0 ); + color: rgb(255, 255, 255); + text-shadow: 3px 2px 5px rgb( 0, 0, 0 ); - z-index: 5; + z-index: 5; } - #keyBindsLabel { - bottom: 300px; - } + #keyBindsLabel { + bottom: 300px; + } - #keyLockLabel span, #keyBindsLabel span { - font-size: 30px; - } + #keyLockLabel span, #keyBindsLabel span { + font-size: 30px; + } #helpWindow { - width: 75%; - height: 90%; + width: 75%; + height: 90%; - position: absolute; - margin: auto; - top: 0; - right: 0; - bottom: 0; - left: 0; + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; - display: grid; - grid-template-rows: 90% 10%; - justify-items: center; + display: grid; + grid-template-rows: 90% 10%; + justify-items: center; - z-index: 6; + z-index: 6; } - #helpWindow iframe { - width: 100%; - height: 100%; + #helpWindow iframe { + width: 100%; + height: 100%; - display: block; - } + display: block; + } - #helpWindow .close { + #helpWindow .close { width: 150px; - height: 50px; - - margin: auto; + height: 50px; + + margin: auto; - font-size: 18px; + font-size: 18px; border-radius: 10px; border: none; @@ -1023,10 +1062,10 @@ button:focus { outline: none; } #helpWindow .close:active { background-color: rgb( 190, 190, 190 ); padding: 0; - } + } @media ( max-width: 1024px ) { - #helpWindow { - width: 80%; - } + #helpWindow { + width: 80%; + } } \ No newline at end of file diff --git a/nui/radar.html b/nui/radar.html index c15d446..37c1194 100644 --- a/nui/radar.html +++ b/nui/radar.html @@ -1,3 +1,35 @@ + + @@ -6,7 +38,7 @@
-Wraith ARS 2X
-FRONT
-REAR
-FRONT
+REAR
+
-
-
+
+
+
- LOCKED
-LOCKED
-LOCKED
+LOCKED
+Plate Reader
-Radar Scale
-1.00x
-Radar Scale
+1.00x
+Remote Scale
-1.00x
-Remote Scale
+1.00x
+Reader Scale
-1.00x
-Reader Scale
+1.00x
+Safezone: 0px
- -Safezone: 0px
+ +Radar key lock
-Radar keybinds set for a
+ + +Radar key lock
+Radar keybinds set for a
-