diff --git a/cl_plate_reader.lua b/cl_plate_reader.lua new file mode 100644 index 0000000..815bd58 --- /dev/null +++ b/cl_plate_reader.lua @@ -0,0 +1,181 @@ +--[[----------------------------------------------------------------------- + + Wraith ARS 2X + Created by WolfKnight + +-----------------------------------------------------------------------]]-- + +READER = {} + +--[[---------------------------------------------------------------------------------- + Plate reader variables + + NOTE - This is not a config, do not touch anything unless you know what + you are actually doing. +----------------------------------------------------------------------------------]]-- +READER.vars = +{ + -- Whether or not the radar's UI is visible + displayed = 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, + + boloPlate = "", + + cams = { + ["front"] = { + plate = "", + index = "", + locked = false + }, + + ["rear"] = { + plate = "", + index = "", + lockec = false + } + } +} + +-- Runs when the "Toggle Display" button is pressed on the plate reder box +RegisterNUICallback( "togglePlateReaderDisplay", function() + -- Toggle the display state + READER:ToggleDisplayState() +end ) + +-- Runs when the "Toggle Display" button is pressed on the plate reder box +RegisterNUICallback( "setBoloPlate", function( plate, cb ) + READER:SetBoloPlate( plate ) +end ) + +-- Gets the display state +function READER:GetDisplayState() + return self.vars.displayed +end + +-- Toggles the display state of the radar system +function READER:ToggleDisplayState() + -- Toggle the display variable + self.vars.displayed = not self.vars.displayed + + -- Send the toggle message to the NUI side + SendNUIMessage( { _type = "setReaderDisplayState", state = self:GetDisplayState() } ) +end + +-- Sets the display's hidden state to the given state +function READER:SetDisplayHidden( state ) + self.vars.hidden = state +end + +-- Returns if the display is hidden +function READER:GetDisplayHidden() + return self.vars.hidden +end + +function READER:GetPlate( cam ) + return self.vars.cams[cam].plate +end + +function READER:SetPlate( cam, plate ) + self.vars.cams[cam].plate = plate +end + +function READER:GetIndex( cam ) + return self.vars.cams[cam].index +end + +function READER:SetIndex( cam, index ) + self.vars.cams[cam].index = index +end + +function READER:GetBoloPlate() + return self.vars.boloPlate +end + +function READER:SetBoloPlate( plate ) + self.vars.boloPlate = plate +end + +function READER:GetCamLocked( cam ) + return self.vars.cams[cam].locked +end + +function READER:LockCam( cam ) + if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then + self.vars.cams[cam].locked = not self.vars.cams[cam].locked + + SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ) } ) + SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) + end +end + +function READER:CanPerformMainTask() + return self.vars.displayed and not self.vars.hidden +end + +function READER:GetCamFromNum( relPos ) + if ( relPos == 1 ) then + return "front" + elseif ( relPos == -1 ) then + return "rear" + end +end + +function READER:Main() + if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then + for i = 1, -1, -2 do + local start = GetEntityCoords( PLY.veh ) + local offset = GetOffsetFromEntityInWorldCoords( PLY.veh, 0.0, ( 40.0 * i ), 0.0 ) + local veh = UTIL:GetVehicleInDirection( PLY.veh, start, offset ) + + local cam = self:GetCamFromNum( i ) + + if ( DoesEntityExist( veh ) and IsEntityAVehicle( veh ) and not self:GetCamLocked( cam ) ) then + local plate = GetVehicleNumberPlateText( veh ) + local index = GetVehicleNumberPlateTextIndex( veh ) + + if ( self:GetPlate( cam ) ~= plate ) then + self:SetPlate( cam, plate ) + self:SetIndex( cam, index ) + + if ( plate == self:GetBoloPlate() ) then + UTIL:Notify( "DEBUG: BOLO plate hit!" ) + self:LockCam( cam ) + end + + SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) + end + end + end + end +end + +Citizen.CreateThread( function() + while ( true ) do + READER:Main() + + Citizen.Wait( 500 ) + end +end ) + +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 ) + SendNUIMessage( { _type = "setReaderDisplayState", state = false } ) + elseif ( PLY.veh > 0 and PLY.vehClassValid and PLY.inDriverSeat and self:GetDisplayState() and self:GetDisplayHidden() ) then + self:SetDisplayHidden( false ) + SendNUIMessage( { _type = "setReaderDisplayState", state = true } ) + end +end + +Citizen.CreateThread( function() + Citizen.Wait( 100 ) + + while ( true ) do + READER:RunDisplayValidationCheck() + + Citizen.Wait( 500 ) + end +end ) \ No newline at end of file diff --git a/cl_radar.lua b/cl_radar.lua index 600765d..1d15c43 100644 --- a/cl_radar.lua +++ b/cl_radar.lua @@ -50,7 +50,7 @@ end ) --[[---------------------------------------------------------------------------------- Player info variables ----------------------------------------------------------------------------------]]-- -local PLY = +PLY = { ped = PlayerPedId(), veh = nil, @@ -77,95 +77,6 @@ Citizen.CreateThread( function() end end ) ---[[---------------------------------------------------------------------------------- - Plate reader variables - - NOTE - This is not a config, do not touch anything unless you know what - you are actually doing. -----------------------------------------------------------------------------------]]-- -READER = {} -READER.vars = -{ - -- Whether or not the radar's UI is visible - displayed = true, - - -- 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, - - cams = { - ["front"] = { - plate = nil, - index = nil - }, - - ["rear"] = { - plate = nil, - index = nil - } - } -} - -function READER:GetPlate( cam ) - return self.vars[cam].plate -end - -function READER:SetPlate( cam, plate ) - self.vars.cams[cam].plate = plate -end - -function READER:GetIndex( cam ) - return self.vars[cam].index -end - -function READER:SetIndex( cam, index ) - self.vars.cams[cam].index = index -end - -function READER:CanPerformMainTask() - return self.vars.displayed and not self.vars.hidden -end - -function READER:GetCamFromNum( relPos ) - if ( relPos == 1 ) then - return "front" - elseif ( relPos == -1 ) then - return "rear" - end -end - -function READER:Main() - if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then - for i = 1, -1, -2 do - local start = GetEntityCoords( PLY.veh ) - local offset = GetOffsetFromEntityInWorldCoords( PLY.veh, 0.0, ( 50.0 * i ), 0.0 ) - local veh = UTIL:GetVehicleInDirection( PLY.veh, start, offset ) - - if ( DoesEntityExist( veh ) and IsEntityAVehicle( veh ) ) then - local plate = GetVehicleNumberPlateText( veh ) - local index = GetVehicleNumberPlateTextIndex( veh ) - - local cam = self:GetCamFromNum( i ) - - if ( self:GetPlate( cam ) ~= plate ) then - self:SetPlate( cam, plate ) - self:SetIndex( cam, index ) - - SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) - end - end - end - end -end - -Citizen.CreateThread( function() - while ( true ) do - READER:Main() - - Citizen.Wait( 500 ) - end -end ) - --[[---------------------------------------------------------------------------------- Radar variables @@ -173,6 +84,7 @@ end ) NOTE - This is not a config, do not touch anything unless you know what you are actually doing. ----------------------------------------------------------------------------------]]-- +RADAR = {} RADAR.vars = { -- Whether or not the radar's UI is visible @@ -196,9 +108,6 @@ RADAR.vars = ["same"] = 3, ["opp"] = 3, - -- Future feature! - -- ["alert"] = true, - -- The volume of the audible beep ["beep"] = 1.0, @@ -458,7 +367,7 @@ end -- Returns if the fast limit option should be available for the radar function RADAR:IsFastLimitAllowed() - return self.config.allow_fast_limit + return CONFIG.allow_fast_limit end -- Only create the functions if the fast limit config option is enabled @@ -1351,7 +1260,7 @@ end NUI callback ----------------------------------------------------------------------------------]]-- -- Runs when the "Toggle Display" button is pressed on the remote control -RegisterNUICallback( "toggleDisplay", function() +RegisterNUICallback( "toggleRadarDisplay", function() -- Toggle the display state RADAR:ToggleDisplayState() end ) @@ -1649,7 +1558,7 @@ Citizen.CreateThread( function() while ( true ) do RADAR:RunDisplayValidationCheck() - Citizen.Wait( 100 ) + Citizen.Wait( 500 ) end end ) @@ -1669,32 +1578,42 @@ Citizen.CreateThread( function() end end ) -function RADAR:RunControlManager() +function RunControlManager() -- 'Z' key, toggles debug mode --[[ if ( IsDisabledControlJustPressed( 1, 20 ) ) then self.config.debug_mode = not self.config.debug_mode end ]] - if ( not self:GetKeyLockState() ) then + if ( not RADAR:GetKeyLockState() ) then -- Opens the remote control - if ( IsDisabledControlJustPressed( 1, self.config.remote_control_key ) ) then - self:OpenRemote() + if ( IsDisabledControlJustPressed( 1, CONFIG.remote_control_key ) ) then + RADAR:OpenRemote() end -- Locks speed from front antenna - if ( IsDisabledControlJustPressed( 1, self.config.front_lock_key ) ) then - self:LockAntennaSpeed( "front" ) + if ( IsDisabledControlJustPressed( 1, CONFIG.front_lock_key ) ) then + RADAR:LockAntennaSpeed( "front" ) end -- Locks speed from rear antenna - if ( IsDisabledControlJustPressed( 1, self.config.rear_lock_key ) ) then - self:LockAntennaSpeed( "rear" ) + if ( IsDisabledControlJustPressed( 1, CONFIG.rear_lock_key ) ) then + RADAR:LockAntennaSpeed( "rear" ) + end + + -- Locks front plate reader + if ( IsDisabledControlJustPressed( 1, CONFIG.plate_front_lock_key ) ) then + READER:LockCam( "front" ) + end + + -- Locks front plate reader + if ( IsDisabledControlJustPressed( 1, CONFIG.plate_rear_lock_key ) ) then + READER:LockCam( "rear" ) end end -- Toggles the key lock state - if ( IsDisabledControlJustPressed( 1, self.config.key_lock_key ) ) then - self:ToggleKeyLock() + if ( IsDisabledControlJustPressed( 1, CONFIG.key_lock_key ) ) then + RADAR:ToggleKeyLock() end -- Shortcut to restart the resource @@ -1706,7 +1625,7 @@ end -- Control manager Citizen.CreateThread( function() while ( true ) do - RADAR:RunControlManager() + RunControlManager() Citizen.Wait( 0 ) end diff --git a/cl_utils.lua b/cl_utils.lua index dec87bf..e65fc67 100644 --- a/cl_utils.lua +++ b/cl_utils.lua @@ -92,7 +92,7 @@ function UTIL:DrawDebugText( x, y, scale, centre, text ) end function UTIL:DrawDebugSphere( x, y, z, r, col ) - if ( RADAR.config.debug_mode ) then + if ( CONFIG.debug_mode ) then local col = col or { 255, 255, 255, 255 } DrawMarker( 28, x, y, z, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, r, r, r, col[1], col[2], col[3], col[4], false, true, 2, false, false, false, false ) @@ -100,7 +100,7 @@ function UTIL:DrawDebugSphere( x, y, z, r, col ) end function UTIL:DrawDebugLine( startP, endP, col ) - if ( RADAR.config.debug_mode ) then + if ( CONFIG.debug_mode ) then local col = col or { 255, 255, 255, 255 } DrawLine( startP, endP, col[1], col[2], col[3], col[4] ) @@ -108,7 +108,7 @@ function UTIL:DrawDebugLine( startP, endP, col ) end function UTIL:DebugPrint( text ) - if ( RADAR.config.debug_mode ) then + if ( CONFIG.debug_mode ) then print( text ) end end diff --git a/config.lua b/config.lua index fe6c1b3..ed67656 100644 --- a/config.lua +++ b/config.lua @@ -6,29 +6,36 @@ ------------------------------------------------------------------------]]-- -- Do not touch this -RADAR = {} -RADAR.config = {} +CONFIG = {} -- Radar Control Panel key -- The default key to open the radar control panel is 166 (F5 - INPUT_SELECT_CHARACTER_MICHAEL) -RADAR.config.remote_control_key = 166 +CONFIG.remote_control_key = 166 -- Radar front antenna lock/unlock Key -- The default key to lock/unlock the front antenna is 111 (Numpad 8 - INPUT_VEH_FLY_PITCH_UP_ONLY) -RADAR.config.front_lock_key = 111 +CONFIG.front_lock_key = 111 -- Radar rear antenna lock/unlock Key -- The default key to lock/unlock the rear antenna is 112 (Numpad 5 - INPUT_VEH_FLY_PITCH_DOWN_ONLY) -RADAR.config.rear_lock_key = 112 +CONFIG.rear_lock_key = 112 -- Radar key lock key -- The default key to enable/disable the radar key lock is 311 (K - INPUT_REPLAY_SHOWHOTKEY) -RADAR.config.key_lock_key = 311 +CONFIG.key_lock_key = 311 + +-- Plate reader front lock/unlock Key +-- The default key to lock/unlock the front plate reader is 118 (Numpad 9 - INPUT_VEH_FLY_SELECT_TARGET_RIGHT) +CONFIG.plate_front_lock_key = 118 + +-- Plate reader rear lock/unlock Key +-- The default key to lock/unlock the rear plate reader is 109 (Numpad 6 - INPUT_VEH_FLY_ROLL_RIGHT_ONLY) +CONFIG.plate_rear_lock_key = 109 -- Radar fast limit locking -- 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 -RADAR.config.allow_fast_limit = true +CONFIG.allow_fast_limit = true -- Debug mode -RADAR.config.debug_mode = false \ No newline at end of file +CONFIG.debug_mode = false \ No newline at end of file diff --git a/fxmanifest.lua b/fxmanifest.lua index 826fb8b..231054e 100644 --- a/fxmanifest.lua +++ b/fxmanifest.lua @@ -31,4 +31,5 @@ server_script 'sv_saving.lua' client_script 'config.lua' client_script 'cl_utils.lua' -client_script 'cl_radar.lua' \ No newline at end of file +client_script 'cl_radar.lua' +client_script 'cl_plate_reader.lua' \ No newline at end of file diff --git a/nui/radar.css b/nui/radar.css index 5feb0a4..2c44ec3 100644 --- a/nui/radar.css +++ b/nui/radar.css @@ -741,6 +741,97 @@ button:focus { outline: none; } color: rgb( 100, 100, 100 ); } +#plateReaderBox { + width: 225px; + height: 300px; + + position: absolute; + margin: auto; + top: 0; + right: 0; + bottom: 0; + left: 0; + + /* background-color: rgb( 50, 54, 45 ); */ + background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); + border: 3px solid rgb( 0, 0, 0 ); + + /* for testing */ + z-index: 100; +} + #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; + padding: 0; + padding-bottom: 15px; + margin-bottom: -15px; + border: 3px solid rgb( 0, 0, 0 ); + } + + #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; @@ -752,14 +843,8 @@ button:focus { outline: none; } bottom: 0; left: 0; - /* background-color: rgb( 0, 255, 55 ); */ - /* background-color: transparent; */ background-color: rgb( 50, 54, 45 ); - /* display: grid; - grid-template-columns: 1fr 1fr; - gap: 10px; */ - z-index: 3; } #uiSettingsBox .title { @@ -771,14 +856,14 @@ button:focus { outline: none; } background-color: rgb( 20, 22, 18 ); } - #uiSettingsBox .radar_settings { + #uiSettingsBox .header { width: 100%; } #uiSettingsBox .scaling_container { height: 225px; display: grid; - grid-template-rows: 1fr 1fr; + grid-template-rows: 1fr 1fr 1fr; } #uiSettingsBox .scaling { diff --git a/nui/radar.html b/nui/radar.html index 4952054..5f1a2cf 100644 --- a/nui/radar.html +++ b/nui/radar.html @@ -114,7 +114,7 @@
FRONT ANTENNA
@@ -196,14 +196,30 @@LOCKED
-LOCKED
+LOCKED
+LOCKED
Plate Reader
+UI Settings