diff --git a/cl_plate_reader.lua b/cl_plate_reader.lua index ff1ac68..3b005cf 100644 --- a/cl_plate_reader.lua +++ b/cl_plate_reader.lua @@ -141,17 +141,23 @@ function READER:GetCamLocked( cam ) end -- Locks the given reader -function READER:LockCam( cam, playBeep, isBolo ) +function READER:LockCam( cam, playBeep, isBolo, override ) -- Check that plate readers can actually be locked - if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then + if ( PLY:VehicleStateValid() and self:CanPerformMainTask() and self:GetPlate( cam ) ~= "" ) 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 } ) - -- Play a beep if ( self:GetCamLocked( cam ) ) then + -- Here we check if the override parameter is valid, if so then we set the reader's plate data to the + -- plate data provided in the override table. + if ( override ~= nil ) then + self:SetPlate( cam, override[1] ) + self:SetIndex( cam, override[2] ) + + self:ForceNUIUpdate( false ) + end + if ( playBeep ) then SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "plateAudio" ) } ) end @@ -163,6 +169,9 @@ function READER:LockCam( cam, playBeep, isBolo ) -- 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 + + -- Tell the NUI side to show/hide the lock icon + SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ), isBolo = isBolo } ) end end @@ -180,6 +189,30 @@ function READER:GetCamFromNum( relPos ) end end +-- Forces an NUI update, used by the passenger control system +function READER:ForceNUIUpdate( lock ) + for cam in UTIL:Values( { "front", "rear" } ) do + local plate = self:GetPlate( cam ) + local index = self:GetIndex( cam ) + + if ( plate ~= "" and index ~= "" ) then + SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) + + if ( lock ) then + SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ), isBolo = false } ) + end + end + end +end + +-- Returns a table with both antenna's speed data and directions +function READER:GetCameraDataPacket( cam ) + return { + self:GetPlate( cam ), + self:GetIndex( cam ) + } +end + RegisterNetEvent( "wk:togglePlateLock" ) AddEventHandler( "wk:togglePlateLock", function( cam, beep, bolo ) READER:LockCam( cam, beep, bolo ) @@ -264,6 +297,8 @@ function READER:Main() -- Automatically lock the plate if the scanned plate matches the BOLO if ( plate == self:GetBoloPlate() ) then self:LockCam( cam, false, true ) + + SYNC:LockReaderCam( cam, READER:GetCameraDataPacket( cam ) ) end -- Send the plate information to the NUI side to update the UI diff --git a/cl_radar.lua b/cl_radar.lua index 335ccdc..3a7abbe 100644 --- a/cl_radar.lua +++ b/cl_radar.lua @@ -79,6 +79,8 @@ local function RegisterKeyBinds() RegisterCommand( "radar_fr_cam", function() if ( not RADAR:GetKeyLockState() ) then READER:LockCam( "front", true, false ) + + SYNC:LockReaderCam( "front", READER:GetCameraDataPacket( "front" ) ) end end ) RegisterKeyMapping( "radar_fr_cam", "Front Plate Reader Lock/Unlock", "keyboard", CONFIG.keyDefaults.plate_front_lock ) @@ -87,6 +89,8 @@ local function RegisterKeyBinds() RegisterCommand( "radar_bk_cam", function() if ( not RADAR:GetKeyLockState() ) then READER:LockCam( "rear", true, false ) + + SYNC:LockReaderCam( "rear", READER:GetCameraDataPacket( "rear" ) ) end end ) RegisterKeyMapping( "radar_bk_cam", "Rear Plate Reader Lock/Unlock", "keyboard", CONFIG.keyDefaults.plate_rear_lock ) @@ -1279,7 +1283,7 @@ function RADAR:ResetAntenna( ant ) self:ResetAntennaSpeedLock( ant ) end --- Returns a table with both antenna's speed data and directions +-- Returns a table with the given antenna's speed data and directions function RADAR:GetAntennaDataPacket( ant ) return { self:GetAntennaSpeed( ant ), diff --git a/cl_sync.lua b/cl_sync.lua index 352bfcb..94e1029 100644 --- a/cl_sync.lua +++ b/cl_sync.lua @@ -33,6 +33,84 @@ DecorRegister( "wk_wars2x_sync_remoteOpen", 2 ) +--[[---------------------------------------------------------------------------------- + Plate reader sync variables and functions +----------------------------------------------------------------------------------]]-- +READER.backupData = +{ + cams = { + ["front"] = nil, + ["rear"] = nil + } +} + +function READER:GetReaderDataForSync() + return { + ["front"] = self.vars.cams["front"], + ["rear"] = self.vars.cams["rear"] + } +end + +function READER:SetReaderCamData( cam, data ) + if ( type( data ) == "table" ) then + self.vars.cams[cam] = data + end +end + +function READER:GetBackupReaderData( cam ) + return self.backupData.cams[cam] +end + +function READER:SetBackupReaderData( cam, data ) + self.backupData.cams[cam] = data +end + +function READER:IsThereBackupData() + return self:GetBackupReaderData( "front" ) ~= nil or self:GetBackupReaderData( "rear" ) ~= nil +end + +function READER:BackupData() + local data = self:GetReaderDataForSync() + + for cam in UTIL:Values( { "front", "rear" } ) do + if ( self:GetBackupReaderData( cam ) == nil ) then + self:SetBackupReaderData( cam, data[cam] ) + end + end +end + +function READER:LoadDataFromDriver( data ) + -- Backup the local data first + self:BackupData() + + -- As a precaution, give the system 50ms before it replaces the local data with the data from the driver + Citizen.SetTimeout( 50, function() + -- Set the camera data + for cam in UTIL:Values( { "front", "rear" } ) do + self:SetReaderCamData( cam, data[cam] ) + + self:ForceNUIUpdate( true ) + end + end ) +end + +function READER:RestoreFromBackup() + -- Iterate through the cameras and restore their backups + for cam in UTIL:Values( { "front", "rear" } ) do + -- Get the camera backup data + local camData = self:GetBackupReaderData( cam ) + + -- Restore the camera data + if ( camData ~= nil ) then + self:SetReaderCamData( cam, camData ) + + -- Clear the backup + self:SetBackupReaderData( cam, nil ) + end + end +end + + --[[---------------------------------------------------------------------------------- Radar sync variables and functions ----------------------------------------------------------------------------------]]-- @@ -267,6 +345,12 @@ function SYNC:SendUpdatedOMData( data ) end ) end +function SYNC:LockReaderCam( cam, data ) + self:SyncData( function( ply ) + TriggerServerEvent( "wk_wars2x_sync:sendLockCameraPlate", ply, cam, data ) + end ) +end + -- Requests radar data from the driver if the player has just entered a valid vehicle as a front seat passenger function SYNC:SyncDataOnEnter() -- Make sure passenger view is allowed, also, using PLY:IsPassenger() already checks that the player's @@ -284,6 +368,7 @@ function SYNC:SyncDataOnEnter() if ( RADAR:IsThereBackupData() ) then -- Restore the local data RADAR:RestoreFromBackup() + READER:RestoreFromBackup() end end end @@ -324,18 +409,25 @@ AddEventHandler( "wk_wars2x_sync:receiveLockAntennaSpeed", function( antenna, da RADAR:LockAntennaSpeed( antenna, data, true ) end ) +RegisterNetEvent( "wk_wars2x_sync:receiveLockCameraPlate" ) +AddEventHandler( "wk_wars2x_sync:receiveLockCameraPlate", function( camera, data ) + READER:LockCam( camera, true, false, data ) +end ) + -- Event for gathering the radar data and sending it to another player RegisterNetEvent( "wk_wars2x_sync:getRadarDataFromDriver" ) AddEventHandler( "wk_wars2x_sync:getRadarDataFromDriver", function( playerFor ) - local data = RADAR:GetRadarDataForSync() + local radarData = RADAR:GetRadarDataForSync() + local readerData = READER:GetReaderDataForSync() - TriggerServerEvent( "wk_wars2x_sync:sendRadarDataForPassenger", playerFor, data ) + TriggerServerEvent( "wk_wars2x_sync:sendRadarDataForPassenger", playerFor, { radarData, readerData } ) end ) -- Event for receiving radar data from another player RegisterNetEvent( "wk_wars2x_sync:receiveRadarData" ) AddEventHandler( "wk_wars2x_sync:receiveRadarData", function( data ) - RADAR:LoadDataFromDriver( data ) + RADAR:LoadDataFromDriver( data[1] ) + READER:LoadDataFromDriver( data[2] ) end ) -- Event for receiving updated operator menu data from another player diff --git a/sv_sync.lua b/sv_sync.lua index c61bc32..b42c3c0 100644 --- a/sv_sync.lua +++ b/sv_sync.lua @@ -57,6 +57,12 @@ AddEventHandler( "wk_wars2x_sync:sendLockAntennaSpeed", function( target, ant, d TriggerClientEvent( "wk_wars2x_sync:receiveLockAntennaSpeed", target, ant, data ) end ) +RegisterNetEvent( "wk_wars2x_sync:sendLockCameraPlate" ) +AddEventHandler( "wk_wars2x_sync:sendLockCameraPlate", function( target, cam, data ) + print( "[wk_wars2x]: Received \"wk_wars2x_sync:sendLockCameraPlate\" event from " .. GetPlayerName( source ) .. " (" .. tostring( source ) .. ") for " .. GetPlayerName( target ) .. " (" .. tostring( target ) .. ")" ) + TriggerClientEvent( "wk_wars2x_sync:receiveLockCameraPlate", target, cam, data ) +end ) + --[[---------------------------------------------------------------------------------- Radar data sync server events