Comments and formatting

This commit is contained in:
Dan
2020-02-18 14:04:52 +00:00
parent c8de750a1e
commit d6511b8b49
9 changed files with 418 additions and 260 deletions

View File

@@ -15,26 +15,30 @@ READER = {}
----------------------------------------------------------------------------------]]-- ----------------------------------------------------------------------------------]]--
READER.vars = READER.vars =
{ {
-- Whether or not the radar's UI is visible -- Whether or not the plate reader's UI is visible
displayed = false, displayed = false,
-- Whether or not the radar should be hidden, e.g. the display is active but the player then steps -- Whether or not the plate reader should be hidden, e.g. the display is active but the player then steps
-- out of their vehicle -- out of their vehicle
hidden = false, hidden = false,
-- The BOLO plate
boloPlate = "", boloPlate = "",
-- Cameras, this table contains all of the data needed for operation of the front and rear plate reader
cams = { cams = {
-- Variables for the front camera
["front"] = { ["front"] = {
plate = "", plate = "", -- The current plate caught by the reader
index = "", index = "", -- The index of the current plate
locked = false locked = false -- If the reader is locked
}, },
-- Variables for the rear camera
["rear"] = { ["rear"] = {
plate = "", plate = "", -- The current plate caught by the reader
index = "", index = "", -- The index of the current plate
lockec = false locked = false -- If the reader is locked
} }
} }
} }
@@ -44,7 +48,7 @@ function READER:GetDisplayState()
return self.vars.displayed return self.vars.displayed
end end
-- Toggles the display state of the radar system -- Toggles the display state of the plate reader system
function READER:ToggleDisplayState() function READER:ToggleDisplayState()
-- Toggle the display variable -- Toggle the display variable
self.vars.displayed = not self.vars.displayed self.vars.displayed = not self.vars.displayed
@@ -63,48 +67,63 @@ function READER:GetDisplayHidden()
return self.vars.hidden return self.vars.hidden
end end
-- Returns the stored plate for the given reader
function READER:GetPlate( cam ) function READER:GetPlate( cam )
return self.vars.cams[cam].plate return self.vars.cams[cam].plate
end end
-- Sets the plate for the given reader to the given plate
function READER:SetPlate( cam, plate ) function READER:SetPlate( cam, plate )
self.vars.cams[cam].plate = plate self.vars.cams[cam].plate = plate
end end
-- Returns the stored plate index for the given reader
function READER:GetIndex( cam ) function READER:GetIndex( cam )
return self.vars.cams[cam].index 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 ) function READER:SetIndex( cam, index )
self.vars.cams[cam].index = index self.vars.cams[cam].index = index
end end
-- Returns the bolo plate
function READER:GetBoloPlate() function READER:GetBoloPlate()
return self.vars.boloPlate return self.vars.boloPlate
end end
-- Sets the bolo plate to the given plate
function READER:SetBoloPlate( plate ) function READER:SetBoloPlate( plate )
self.vars.boloPlate = plate self.vars.boloPlate = plate
UTIL:Notify( "BOLO plate set to: " .. plate ) UTIL:Notify( "BOLO plate set to: " .. plate )
end end
-- Returns if the given reader is locked
function READER:GetCamLocked( cam ) function READER:GetCamLocked( cam )
return self.vars.cams[cam].locked return self.vars.cams[cam].locked
end end
-- Locks the given reader
function READER:LockCam( cam ) function READER:LockCam( cam )
-- Check that plate readers can actually be locked
if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then
-- Toggle the lock state
self.vars.cams[cam].locked = not self.vars.cams[cam].locked 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 ) } ) SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ) } )
-- Play a beep
SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } ) SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } )
end end
end end
-- Returns if the plate reader system can perform tasks
function READER:CanPerformMainTask() function READER:CanPerformMainTask()
return self.vars.displayed and not self.vars.hidden return self.vars.displayed and not self.vars.hidden
end end
-- Returns if the given relative position value is for front or rear
function READER:GetCamFromNum( relPos ) function READER:GetCamFromNum( relPos )
if ( relPos == 1 ) then if ( relPos == 1 ) then
return "front" return "front"
@@ -119,32 +138,56 @@ RegisterNUICallback( "togglePlateReaderDisplay", function()
READER:ToggleDisplayState() READER:ToggleDisplayState()
end ) end )
-- Runs when the "Toggle Display" button is pressed on the plate reder box -- Runs when the "Set BOLO Plate" button is pressed on the plate reader box
RegisterNUICallback( "setBoloPlate", function( plate, cb ) RegisterNUICallback( "setBoloPlate", function( plate, cb )
-- Set the BOLO plate
READER:SetBoloPlate( plate ) READER:SetBoloPlate( plate )
end ) end )
-- This is the main function that runs and scans all vehicles in front and behind the patrol vehicle
function READER:Main() function READER:Main()
-- Check that the system can actually run
if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then 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
local start = GetEntityCoords( PLY.veh ) -- Get the world position of the player's vehicle
local offset = GetOffsetFromEntityInWorldCoords( PLY.veh, 0.0, ( 40.0 * i ), 0.0 ) 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 the end position 40m 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 ) local veh = UTIL:GetVehicleInDirection( PLY.veh, start, offset )
-- Get the plate reader text for front/rear
local cam = self:GetCamFromNum( i ) 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 licence plate text from the vehicle
local plate = GetVehicleNumberPlateText( veh ) local plate = GetVehicleNumberPlateText( veh )
-- Get the licence plate index from the vehicle
local index = GetVehicleNumberPlateTextIndex( veh ) 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 if ( self:GetPlate( cam ) ~= plate ) then
-- Set the plate for the current reader
self:SetPlate( cam, plate ) self:SetPlate( cam, plate )
-- Set the plate index for the current reader
self:SetIndex( cam, index ) 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 ) self:LockCam( cam )
end end
-- Send the plate information to the NUI side to update the UI
SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } ) SendNUIMessage( { _type = "changePlate", cam = cam, plate = plate, index = index } )
end end
end end
@@ -152,14 +195,20 @@ function READER:Main()
end end
end end
-- Main thread
Citizen.CreateThread( function() Citizen.CreateThread( function()
while ( true ) do while ( true ) do
-- Run the main plate reader function
READER:Main() READER:Main()
-- Wait half a second
Citizen.Wait( 500 ) Citizen.Wait( 500 )
end 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
function READER:RunDisplayValidationCheck() 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 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 )
@@ -170,12 +219,15 @@ function READER:RunDisplayValidationCheck()
end end
end end
-- Runs the display validation check for the radar
Citizen.CreateThread( function() Citizen.CreateThread( function()
Citizen.Wait( 100 ) Citizen.Wait( 100 )
while ( true ) do while ( true ) do
-- Run the check
READER:RunDisplayValidationCheck() READER:RunDisplayValidationCheck()
-- Wait half a second
Citizen.Wait( 500 ) Citizen.Wait( 500 )
end end
end ) end )

View File

@@ -35,13 +35,17 @@ end )
----------------------------------------------------------------------------------]]-- ----------------------------------------------------------------------------------]]--
local spawned = false local spawned = false
-- Runs every time the player spawns, but the additional check means it only runs the first time
-- the player spawns
AddEventHandler( "playerSpawned", function() AddEventHandler( "playerSpawned", function()
if ( not spawned ) then if ( not spawned ) then
-- Ask the server to get the player's saved UI data
TriggerServerEvent( "wk:getUiData" ) TriggerServerEvent( "wk:getUiData" )
spawned = true spawned = true
end end
end ) end )
-- Grabs the saved UI data sent by the server and forwards it to the NUI side
RegisterNetEvent( "wk:loadUiData" ) RegisterNetEvent( "wk:loadUiData" )
AddEventHandler( "wk:loadUiData", function( data ) AddEventHandler( "wk:loadUiData", function( data )
SendNUIMessage( { _type = "loadUiSettings", data = data } ) SendNUIMessage( { _type = "loadUiSettings", data = data } )
@@ -1526,15 +1530,21 @@ end
-- Main thread -- Main thread
Citizen.CreateThread( function() Citizen.CreateThread( function()
-- Remove the NUI focus just in case
SetNuiFocus( false, false ) SetNuiFocus( false, false )
-- Run the function to cache the number of rays, this way a hard coded number is never needed
RADAR:CacheNumRays() RADAR:CacheNumRays()
-- Update the end coordinates for the ray traces based on the config, again, reduced hard coding
RADAR:UpdateRayEndCoords() RADAR:UpdateRayEndCoords()
-- If the fast limit feature is allowed, create the config in the radar variables
if ( RADAR:IsFastLimitAllowed() ) then if ( RADAR:IsFastLimitAllowed() ) then
RADAR:CreateFastLimitConfig() RADAR:CreateFastLimitConfig()
end end
-- Run the main radar function
while ( true ) do while ( true ) do
RADAR:Main() RADAR:Main()
@@ -1542,6 +1552,9 @@ Citizen.CreateThread( function()
end 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
function RADAR:RunDisplayValidationCheck() 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 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 )
@@ -1552,28 +1565,38 @@ function RADAR:RunDisplayValidationCheck()
end end
end end
-- Runs the display validation check for the radar
Citizen.CreateThread( function() Citizen.CreateThread( function()
Citizen.Wait( 100 ) Citizen.Wait( 100 )
while ( true ) do while ( true ) do
-- Run the check
RADAR:RunDisplayValidationCheck() RADAR:RunDisplayValidationCheck()
-- Wait half a second
Citizen.Wait( 500 ) Citizen.Wait( 500 )
end end
end ) end )
-- Update the vehicle pool every 3 seconds -- Update the vehicle pool every 3 seconds
function RADAR:UpdateVehiclePool() function RADAR:UpdateVehiclePool()
-- Only update the vehicle pool if we need to
if ( PLY:VehicleStateValid() and self:CanPerformMainTask() and self:IsEitherAntennaOn() ) then if ( PLY:VehicleStateValid() and self:CanPerformMainTask() and self:IsEitherAntennaOn() ) then
-- Get the active vehicle set
local vehs = self:GetAllVehicles() local vehs = self:GetAllVehicles()
-- Update the vehicle pool
self:SetVehiclePool( vehs ) self:SetVehiclePool( vehs )
end end
end end
-- Runs the vehicle pool updater
Citizen.CreateThread( function() Citizen.CreateThread( function()
while ( true ) do while ( true ) do
-- Update the vehicle pool
RADAR:UpdateVehiclePool() RADAR:UpdateVehiclePool()
-- Wait 3 seconds
Citizen.Wait( 3000 ) Citizen.Wait( 3000 )
end end
end ) end )
@@ -1612,9 +1635,9 @@ function RunControlManager()
end end
-- Shortcut to restart the resource -- Shortcut to restart the resource
if ( IsDisabledControlJustPressed( 1, 167 ) ) then --[[ if ( IsDisabledControlJustPressed( 1, 167 ) ) then
ExecuteCommand( "restart wk_wars2x" ) ExecuteCommand( "restart wk_wars2x" )
end end ]]
end end
-- Control manager -- Control manager

View File

@@ -7,33 +7,45 @@
UTIL = {} UTIL = {}
-- Returns a number to a set number of decimal places
function UTIL:Round( num, numDecimalPlaces ) function UTIL:Round( num, numDecimalPlaces )
return tonumber( string.format( "%." .. ( numDecimalPlaces or 0 ) .. "f", num ) ) 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
function UTIL:FormatSpeed( speed ) 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 if ( speed < 0 or speed > 999 ) then return "Err" end
-- Convert the speed to a string
local text = tostring( speed ) local text = tostring( speed )
local pipes = "" 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 .. "¦" pipes = pipes .. "¦"
end end
-- Return the formatted speed
return pipes .. text return pipes .. text
end end
-- Returns a clamped numerical value based on the given parameters
function UTIL:Clamp( val, min, max ) function UTIL:Clamp( val, min, max )
-- Return the min value if the given value is less than the min
if ( val < min ) then if ( val < min ) then
return min return min
-- Return the max value if the given value is larger than the max
elseif ( val > max ) then elseif ( val > max ) then
return max return max
end end
-- Return the given value if it's between the min and max
return val return val
end end
-- Returns if the given table is empty, includes numerical and non-numerical key values
function UTIL:IsTableEmpty( t ) function UTIL:IsTableEmpty( t )
local c = 0 local c = 0
@@ -52,12 +64,15 @@ function UTIL:Values( xs )
end end
end end
-- Old ray trace function for getting a vehicle in a specific direction from a start point
function UTIL:GetVehicleInDirection( entFrom, coordFrom, coordTo ) function UTIL:GetVehicleInDirection( entFrom, coordFrom, coordTo )
local rayHandle = StartShapeTestCapsule( coordFrom.x, coordFrom.y, coordFrom.z, coordTo.x, coordTo.y, coordTo.z, 5.0, 10, entFrom, 7 ) local rayHandle = StartShapeTestCapsule( coordFrom.x, coordFrom.y, coordFrom.z, coordTo.x, coordTo.y, coordTo.z, 8.0, 10, entFrom, 7 )
local _, hitEntity, endCoords, surfaceNormal, vehicle = GetShapeTestResult( rayHandle ) local _, _, _, _, vehicle = GetShapeTestResult( rayHandle )
return vehicle return vehicle
end 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
function UTIL:GetEntityRelativeDirection( myAng, tarAng ) function UTIL:GetEntityRelativeDirection( myAng, tarAng )
local angleDiff = math.abs( ( myAng - tarAng + 180 ) % 360 - 180 ) local angleDiff = math.abs( ( myAng - tarAng + 180 ) % 360 - 180 )
@@ -70,6 +85,7 @@ function UTIL:GetEntityRelativeDirection( myAng, tarAng )
return 0 return 0
end end
-- Your everyday GTA notification function
function UTIL:Notify( text ) function UTIL:Notify( text )
SetNotificationTextEntry( "STRING" ) SetNotificationTextEntry( "STRING" )
AddTextComponentSubstringPlayerName( text ) AddTextComponentSubstringPlayerName( text )
@@ -91,28 +107,6 @@ function UTIL:DrawDebugText( x, y, scale, centre, text )
DrawText( x, y ) DrawText( x, y )
end end
function UTIL:DrawDebugSphere( x, y, z, r, col )
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 )
end
end
function UTIL:DrawDebugLine( startP, endP, col )
if ( CONFIG.debug_mode ) then
local col = col or { 255, 255, 255, 255 }
DrawLine( startP, endP, col[1], col[2], col[3], col[4] )
end
end
function UTIL:DebugPrint( text )
if ( CONFIG.debug_mode ) then
print( text )
end
end
--[[The MIT License (MIT) --[[The MIT License (MIT)
Copyright (c) 2017 IllidanS4 Copyright (c) 2017 IllidanS4

View File

@@ -8,8 +8,8 @@
-- Do not touch this -- Do not touch this
CONFIG = {} CONFIG = {}
-- Radar Control Panel key -- Remote control key
-- The default key to open the radar control panel is 166 (F5 - INPUT_SELECT_CHARACTER_MICHAEL) -- The default key to open the remote control is 166 (F5 - INPUT_SELECT_CHARACTER_MICHAEL)
CONFIG.remote_control_key = 166 CONFIG.remote_control_key = 166
-- Radar front antenna lock/unlock Key -- Radar front antenna lock/unlock Key

View File

@@ -88,7 +88,6 @@ button:focus { outline: none; }
width: 675px; width: 675px;
height: 200px; height: 200px;
/* Temp centre */
position: absolute; position: absolute;
margin: auto; margin: auto;
top: 0; top: 0;
@@ -160,8 +159,6 @@ button:focus { outline: none; }
grid-template-columns: 45px 50px 150px 35px 50px 135px 35px 135px; grid-template-columns: 45px 50px 150px 35px 50px 135px 35px 135px;
gap: 0 0; gap: 0 0;
/* z-index: 2; */
box-shadow: inset 0px 20px 20px -15px rgba( 0, 0, 0, 0.4 ); box-shadow: inset 0px 20px 20px -15px rgba( 0, 0, 0, 0.4 );
} }
#radar .label { #radar .label {
@@ -194,7 +191,6 @@ button:focus { outline: none; }
background: linear-gradient( to bottom, rgba( 230, 230, 230, 0.8 ), rgb( 40, 168, 40 ) 10%, rgb( 0, 134, 0 ) ); background: linear-gradient( to bottom, rgba( 230, 230, 230, 0.8 ), rgb( 40, 168, 40 ) 10%, rgb( 0, 134, 0 ) );
box-shadow: 0px 0px 3px 0px rgb( 80, 80, 80 ); box-shadow: 0px 0px 3px 0px rgb( 80, 80, 80 );
text-align: center; text-align: center;
/* font-family: 'Heebo-Regular'; */
font-size: 14px; font-size: 14px;
color: rgb( 34, 34, 34 ); color: rgb( 34, 34, 34 );
line-height: 45px; line-height: 45px;
@@ -372,20 +368,13 @@ button:focus { outline: none; }
} }
#rc { #rc {
/* width: 275px;
height: 750px; */
width: 315px; width: 315px;
height: 800px; height: 800px;
position: absolute; position: absolute;
/* top: 0;
bottom: 0;
left: 0;
right: 0; */
top: calc( 50% - ( 800px / 2 ) ); top: calc( 50% - ( 800px / 2 ) );
left: calc( 50% - ( 315px / 2 ) ); left: calc( 50% - ( 315px / 2 ) );
margin: auto; margin: auto;
/* padding-top: 25px; */
padding: 65px 30px 50px 30px; padding: 65px 30px 50px 30px;
display: grid; display: grid;
@@ -394,13 +383,10 @@ button:focus { outline: none; }
align-items: center; align-items: center;
color: white; color: white;
/* background-color: rgb( 50, 50, 50 ); */
background-image: url( "images/rc_bg.png" ); background-image: url( "images/rc_bg.png" );
transition: transform 0.5s; transition: transform 0.5s;
/* clip-path: polygon( 5% 0, 95% 0, 100% 25%, 90% 100%, 10% 100%, 0 25% ); */
/* Settings for scaling */ /* Settings for scaling */
transform: scale( 1.0 ); transform: scale( 1.0 );
transform-origin: 0 0; transform-origin: 0 0;
@@ -415,8 +401,6 @@ button:focus { outline: none; }
background-color: rgb( 200, 200, 200 ); background-color: rgb( 200, 200, 200 );
/* font-family: 'Heebo-Regular'; */
box-shadow: 2px 3px rgb( 100, 100, 100 ); box-shadow: 2px 3px rgb( 100, 100, 100 );
} }
@@ -495,10 +479,8 @@ button:focus { outline: none; }
} }
#rc .label { #rc .label {
/* font-family: 'Heebo-Regular'; */
font-size: 20px; font-size: 20px;
letter-spacing: 1px; letter-spacing: 1px;
/* margin: 5px 0; */
} }
#rc .antenna_btns_container { #rc .antenna_btns_container {
@@ -625,9 +607,6 @@ button:focus { outline: none; }
transform: scale( 1.0 ); transform: scale( 1.0 );
transform-origin: 0 0; transform-origin: 0 0;
/* background-color: rgb(70, 70, 70);
box-shadow: inset 0px 20px 20px -15px rgba( 0, 0, 0, 0.4 ); */
z-index: 1; z-index: 1;
} }
#plateReaderFrame .frame_border { #plateReaderFrame .frame_border {
@@ -644,8 +623,6 @@ button:focus { outline: none; }
background-color: rgb( 20, 22, 18 ); background-color: rgb( 20, 22, 18 );
border-radius: 5px; border-radius: 5px;
/* clip-path: polygon( 20px 2px, 665px 2px, 682px 30%, 682px 70%, 665px 208px, 20px 208px, 3px 70%, 3px 30% ); */
} }
#plateReader { #plateReader {
@@ -721,7 +698,6 @@ button:focus { outline: none; }
font-size: 58px; font-size: 58px;
text-align: center; text-align: center;
letter-spacing: -3px; letter-spacing: -3px;
/* color: rgb(0, 0, 163); */
padding-top: 5px; padding-top: 5px;
margin: 0; margin: 0;
grid-column: 1; grid-column: 1;
@@ -754,11 +730,9 @@ button:focus { outline: none; }
bottom: 0; bottom: 0;
left: 0; left: 0;
/* background-color: rgb( 50, 54, 45 ); */
background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) );
border: 3px solid rgb( 0, 0, 0 ); border: 3px solid rgb( 0, 0, 0 );
/* for testing */
z-index: 4; z-index: 4;
} }
#plateReaderBox .title { #plateReaderBox .title {
@@ -805,10 +779,10 @@ button:focus { outline: none; }
font-family: "Plate-Font"; font-family: "Plate-Font";
text-align: center; text-align: center;
font-size: 38px; font-size: 38px;
text-transform: uppercase;
padding: 0; padding: 0;
padding-bottom: 15px; padding-bottom: 15px;
margin-bottom: -15px; margin-bottom: -15px;
/* border: 3px solid rgb( 0, 0, 0 ); */
} }
#plateReaderBox .close { #plateReaderBox .close {
@@ -845,7 +819,6 @@ button:focus { outline: none; }
bottom: 0; bottom: 0;
left: 0; left: 0;
/* background-color: rgb( 50, 54, 45 ); */
background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) ); background: linear-gradient( to bottom, rgb( 70, 70, 70 ), rgb( 45, 45, 45 ) );
border: 3px solid rgb( 0, 0, 0 ); border: 3px solid rgb( 0, 0, 0 );
@@ -873,10 +846,6 @@ button:focus { outline: none; }
#uiSettingsBox .scaling { #uiSettingsBox .scaling {
height: 70px; height: 70px;
/* display: flex;
justify-content: space-evenly;
align-items: center; */
display: grid; display: grid;
grid-template-columns: 1fr 2fr 1fr; grid-template-columns: 1fr 2fr 1fr;
place-items: center center; place-items: center center;

View File

@@ -16,7 +16,7 @@
<div class="label label_top">FRONT ANTENNA</div> <div class="label label_top">FRONT ANTENNA</div>
<div class="pwr_button_container"> <div class="pwr_button_container">
<div id="pwrBtn" class="pwr_button">PWR</div> <div id="pwrBtn" data-nuitype="togglePower" class="pwr_button">PWR</div>
</div> </div>
<div class="modes_container"> <div class="modes_container">

View File

@@ -14,6 +14,7 @@
var resourceName; var resourceName;
var uiEdited = false; var uiEdited = false;
// All of the audio file names
const audioNames = const audioNames =
{ {
// Beeps // Beeps
@@ -29,6 +30,7 @@ const audioNames =
away: "away.ogg" away: "away.ogg"
} }
// Defines which audio needs to play for which direction
const lockAudio = const lockAudio =
{ {
front: { front: {
@@ -50,7 +52,6 @@ const elements =
remote: $( "#rc" ), remote: $( "#rc" ),
plateReader: $( "#plateReaderFrame" ), plateReader: $( "#plateReaderFrame" ),
// toggleDisplay: $( "#toggleDisplay" ),
pwrBtn: $( "#pwrBtn" ), pwrBtn: $( "#pwrBtn" ),
uiSettingsBtn: $( "#uiSettings" ), uiSettingsBtn: $( "#uiSettings" ),
@@ -163,6 +164,7 @@ const elements =
} }
} }
// Antenna mode values
const modes = const modes =
{ {
off: 0, off: 0,
@@ -171,6 +173,7 @@ const modes =
both: 3 both: 3
} }
// Antenna direction values
const dirs = const dirs =
{ {
none: 0, none: 0,
@@ -190,45 +193,45 @@ elements.uiSettingsBox.hide();
elements.keyLock.label.hide(); elements.keyLock.label.hide();
elements.helpWindow.hide(); elements.helpWindow.hide();
// Sets the action for the "UI SETTINGS" button on the remote to open the UI settings box
elements.uiSettingsBtn.click( function() { elements.uiSettingsBtn.click( function() {
setEleVisible( elements.uiSettingsBox, true ); setEleVisible( elements.uiSettingsBox, true );
} ) } )
// Sets the action for the "PLATE READER" button on the remote to open the plate reader box
elements.plateReaderBtn.click( function() { elements.plateReaderBtn.click( function() {
setEleVisible( elements.plateReaderBox, true ); setEleVisible( elements.plateReaderBox, true );
} ) } )
// Sets the action for the "HELP" button on the remote to open the help window and load the web page
elements.openHelp.click( function() { elements.openHelp.click( function() {
setEleVisible( elements.helpWindow, true ); setEleVisible( elements.helpWindow, true );
loadHelp( true ); loadHelp( true );
} ) } )
// Sets the action for the "Close Help" button under the help window to close the help window and unload the web page
elements.closeHelp.click( function() { elements.closeHelp.click( function() {
setEleVisible( elements.helpWindow, false ); setEleVisible( elements.helpWindow, false );
loadHelp( false ); loadHelp( false );
} ) } )
elements.pwrBtn.click( function() {
togglePower();
} )
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
Setters Setters
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
// Sets the visibility of an element to the given state
function setEleVisible( ele, state ) function setEleVisible( ele, state )
{ {
state ? ele.fadeIn() : ele.fadeOut(); state ? ele.fadeIn() : ele.fadeOut();
if ( state ) {
ele.blur();
}
} }
// Changes the class of the given element so it looks lit up
function setLight( ant, cat, item, state ) function setLight( ant, cat, item, state )
{ {
// Grab the obj element from the elements table
let obj = elements.antennas[ant][cat][item]; let obj = elements.antennas[ant][cat][item];
// Either add the active class or remove it
if ( state ) { if ( state ) {
obj.addClass( cat == "dirs" ? "active_arrow" : "active" ); obj.addClass( cat == "dirs" ? "active_arrow" : "active" );
} else { } else {
@@ -236,48 +239,72 @@ function setLight( ant, cat, item, state )
} }
} }
// Sets the XMIT state of an antenna based on the passed state, makes the fast box display "HLd"
// when the state is false
function setAntennaXmit( ant, state ) function setAntennaXmit( ant, state )
{ {
// Set the light state of the antenna's XMIT icon
setLight( ant, "modes", "xmit", state ); setLight( ant, "modes", "xmit", state );
// Clear the antenna's directional arrows and speeds, display "HLd" in the fast box
if ( !state ) { if ( !state ) {
clearDirs( ant ); clearDirs( ant );
elements.antennas[ant].targetSpeed.html( "¦¦¦" ); elements.antennas[ant].targetSpeed.html( "¦¦¦" );
elements.antennas[ant].fastSpeed.html( "HLd" ); elements.antennas[ant].fastSpeed.html( "HLd" );
// Blank the fast box when the antenna is set to transmit
} else { } else {
elements.antennas[ant].fastSpeed.html( "¦¦¦" ); elements.antennas[ant].fastSpeed.html( "¦¦¦" );
} }
} }
// Sets the mode lights for the given antenna
function setAntennaMode( ant, mode ) function setAntennaMode( ant, mode )
{ {
// Light up the 'same' led if the given mode is the same mode, otherwise blank it
setLight( ant, "modes", "same", mode == modes.same ); setLight( ant, "modes", "same", mode == modes.same );
// Light up the 'opp' led if the given mode is the opp mode, otherwise blank it
setLight( ant, "modes", "opp", mode == modes.opp ); setLight( ant, "modes", "opp", mode == modes.opp );
} }
// Sets the fast light for the given antenna
function setAntennaFastMode( ant, state ) function setAntennaFastMode( ant, state )
{ {
// Lighten or dull the fast led based on the given state
setLight( ant, "fast", "fastLabel", state ); setLight( ant, "fast", "fastLabel", state );
} }
// Sets the lock light for the given antenna
function setAntennaLock( ant, state ) function setAntennaLock( ant, state )
{ {
// Lighten or dull the lock led based on the given state
setLight( ant, "fast", "lockLabel", state ); setLight( ant, "fast", "lockLabel", state );
} }
// Sets the directional arrows light for the given antenna
function setAntennaDirs( ant, dir, fastDir ) function setAntennaDirs( ant, dir, fastDir )
{ {
// Target forward
setLight( ant, "dirs", "fwd", dir == dirs.closing ); setLight( ant, "dirs", "fwd", dir == dirs.closing );
// Target backward
setLight( ant, "dirs", "bwd", dir == dirs.away ); setLight( ant, "dirs", "bwd", dir == dirs.away );
// Fast forward
setLight( ant, "dirs", "fwdFast", fastDir == dirs.closing ); setLight( ant, "dirs", "fwdFast", fastDir == dirs.closing );
// Fast backward
setLight( ant, "dirs", "bwdFast", fastDir == dirs.away ); setLight( ant, "dirs", "bwdFast", fastDir == dirs.away );
} }
// sets the plate lock light for the given plate reader
function setPlateLock( cam, state ) function setPlateLock( cam, state )
{ {
// Get the plate reader lock object
let obj = elements.plates[cam].lock; let obj = elements.plates[cam].lock;
// Add or remove the active class
if ( state ) { if ( state ) {
obj.addClass( "active" ); obj.addClass( "active" );
} else { } else {
@@ -285,6 +312,7 @@ function setPlateLock( cam, state )
} }
} }
// Sets the license text and plate image of the given plate reader
function setPlate( cam, plate, index ) function setPlate( cam, plate, index )
{ {
// Get the plate items // Get the plate items
@@ -309,40 +337,55 @@ function setPlate( cam, plate, index )
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
Clearing functions Clearing functions
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
// Clears the same, opp, fast, and lock leds for the given antenna
function clearModes( ant ) function clearModes( ant )
{ {
// Iterate through the modes and clear them
for ( let i in elements.antennas[ant].modes ) for ( let i in elements.antennas[ant].modes )
{ {
elements.antennas[ant].modes[i].removeClass( "active" ); elements.antennas[ant].modes[i].removeClass( "active" );
} }
// Iterate through the fast leds and clear them
for ( let a in elements.antennas[ant].fast ) for ( let a in elements.antennas[ant].fast )
{ {
elements.antennas[ant].fast[a].removeClass( "active" ); elements.antennas[ant].fast[a].removeClass( "active" );
} }
} }
// Clears the directional arrows for the given antenna
function clearDirs( ant ) function clearDirs( ant )
{ {
// Iterate through the directional arrows and clear them
for ( let i in elements.antennas[ant].dirs ) for ( let i in elements.antennas[ant].dirs )
{ {
elements.antennas[ant].dirs[i].removeClass( "active_arrow" ); elements.antennas[ant].dirs[i].removeClass( "active_arrow" );
} }
} }
// Clears all of the elements of the given antenna
function clearAntenna( ant ) function clearAntenna( ant )
{ {
// Clear the modes
clearModes( ant ); clearModes( ant );
// Clear the directional arrows
clearDirs( ant ); clearDirs( ant );
// Blank the target speed box
elements.antennas[ant].targetSpeed.html( "¦¦¦" ); elements.antennas[ant].targetSpeed.html( "¦¦¦" );
// Blank the fast speed box
elements.antennas[ant].fastSpeed.html( "¦¦¦" ); elements.antennas[ant].fastSpeed.html( "¦¦¦" );
} }
// Clears all the elements on the radar's UI
function clearEverything() function clearEverything()
{ {
// Blank the patrol speed
elements.patrolSpeed.html( "¦¦¦" ); elements.patrolSpeed.html( "¦¦¦" );
// Blank both the antennas
for ( let i in elements.antennas ) for ( let i in elements.antennas )
{ {
clearAntenna( i ); clearAntenna( i );
@@ -353,24 +396,26 @@ function clearEverything()
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
Radar power functions Radar power functions
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
function togglePower() // Simulates the radar unit powering up by lighting all of the elements
{
sendData( "togglePower", null );
}
function poweringUp() function poweringUp()
{ {
// Set the patrol speed container to be fully lit
elements.patrolSpeed.html( "888" ); elements.patrolSpeed.html( "888" );
// Iterate through the front and rear antenna elements
for ( let i of [ "front", "rear" ] ) for ( let i of [ "front", "rear" ] )
{ {
// Get the antenna object to shorten the target reference
let e = elements.antennas[i]; let e = elements.antennas[i];
// Set the target and fast speed box to be fully lit
e.targetSpeed.html( "888" ); e.targetSpeed.html( "888" );
e.fastSpeed.html( "888" ); e.fastSpeed.html( "888" );
// Iterate through the rest of the antenna's elements
for ( let a of [ "dirs", "modes", "fast" ] ) for ( let a of [ "dirs", "modes", "fast" ] )
{ {
// Iterate through the objects for the current category and add the active class
for ( let obj in e[a] ) for ( let obj in e[a] )
{ {
a == "dirs" ? e[a][obj].addClass( "active_arrow" ) : e[a][obj].addClass( "active" ); a == "dirs" ? e[a][obj].addClass( "active_arrow" ) : e[a][obj].addClass( "active" );
@@ -379,17 +424,23 @@ function poweringUp()
} }
} }
// Simulates the 'fully powered' state of the radar unit
function poweredUp() function poweredUp()
{ {
// Completely clear everything
clearEverything(); clearEverything();
// Activate the 'fast' led for both antennas, and make sure the xmit led is off
for ( let ant of [ "front", "rear" ] ) for ( let ant of [ "front", "rear" ] )
{ {
// Even though the clearEverything() function is called above, we run this so the fast window
// displays 'HLd'
setAntennaXmit( ant, false ); setAntennaXmit( ant, false );
setAntennaFastMode( ant, true ); setAntennaFastMode( ant, true );
} }
} }
// Runs the startup process or clears everything, the Lua side calls for the full powered up state
function radarPower( state ) function radarPower( state )
{ {
state ? poweringUp() : clearEverything(); state ? poweringUp() : clearEverything();
@@ -399,17 +450,26 @@ function radarPower( state )
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
Audio Audio
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
// Plays the given audio file name from the audioNames list at the given volume
function playAudio( name, vol ) function playAudio( name, vol )
{ {
// Create the new audio object
let audio = new Audio( "sounds/" + audioNames[name] ); let audio = new Audio( "sounds/" + audioNames[name] );
// Set the volume
audio.volume = vol; audio.volume = vol;
// Play the audio clip
audio.play(); audio.play();
} }
// Plays the verbal lock, this is a separate from the function above as it plays two sounds with a delay
function playLockAudio( ant, dir, vol ) function playLockAudio( ant, dir, vol )
{ {
// Play the front/rear sound
playAudio( ant, vol ); playAudio( ant, vol );
// If the vehicle was closing or away, play that sound too
if ( dir > 0 ) if ( dir > 0 )
{ {
setTimeout( function() { setTimeout( function() {
@@ -422,23 +482,31 @@ function playLockAudio( ant, dir, vol )
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
Radar updating Radar updating
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
// Updates patrol speed as well as the speeds and directional arrows for the given antenna
function updateDisplays( ps, ants ) function updateDisplays( ps, ants )
{ {
// Update the patrol speed
elements.patrolSpeed.html( ps ); elements.patrolSpeed.html( ps );
// Iterate through the antenna data
for ( let ant in ants ) for ( let ant in ants )
{ {
// Make sure there is actually data for the current antenna data
if ( ants[ant] != null ) { if ( ants[ant] != null ) {
// Grab the antenna element from the elements table
let e = elements.antennas[ant]; let e = elements.antennas[ant];
// Update the target and fast speeds
e.targetSpeed.html( ants[ant][0].speed ); e.targetSpeed.html( ants[ant][0].speed );
e.fastSpeed.html( ants[ant][1].speed ); e.fastSpeed.html( ants[ant][1].speed );
// Update the directional arrows
setAntennaDirs( ant, ants[ant][0].dir, ants[ant][1].dir ); setAntennaDirs( ant, ants[ant][0].dir, ants[ant][1].dir );
} }
} }
} }
// Updates all of the mode leds on the radar interface
function settingUpdate( ants ) function settingUpdate( ants )
{ {
for ( let ant in ants ) for ( let ant in ants )
@@ -454,22 +522,30 @@ function settingUpdate( ants )
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
Misc Misc
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
// Displays the given option text and current option value on the radar
function menu( optionText, option ) function menu( optionText, option )
{ {
// Clear everything
clearEverything(); clearEverything();
// Set the target and fast box to the option text
elements.antennas.front.targetSpeed.html( optionText[0] ); elements.antennas.front.targetSpeed.html( optionText[0] );
elements.antennas.front.fastSpeed.html( optionText[1] ); elements.antennas.front.fastSpeed.html( optionText[1] );
// Set the patrol speed to the value
elements.patrolSpeed.html( option ); elements.patrolSpeed.html( option );
} }
// Makes the key lock label fade in then fade out after 2 seconds
function displayKeyLock( state ) function displayKeyLock( state )
{ {
// Set the state label text to enabled or disabled
elements.keyLock.stateLabel.html( state ? "enabled" : "disabled" ); elements.keyLock.stateLabel.html( state ? "enabled" : "disabled" );
// Fade in the label
elements.keyLock.label.fadeIn(); elements.keyLock.label.fadeIn();
// Make the label fade out after 2 seconds
setTimeout( function() { setTimeout( function() {
elements.keyLock.label.fadeOut(); elements.keyLock.label.fadeOut();
}, 2000 ); }, 2000 );
@@ -484,18 +560,22 @@ function sendData( name, data ) {
} ); } );
} }
// Sets the ui edited variable to the given state, this is used in the UI save system
function setUiHasBeenEdited( state ) function setUiHasBeenEdited( state )
{ {
uiEdited = state; uiEdited = state;
} }
// Returns if the UI has been edited
function hasUiBeenEdited() function hasUiBeenEdited()
{ {
return uiEdited; return uiEdited;
} }
// Gathers the UI data and sends it to the Lua side
function sendSaveData() function sendSaveData()
{ {
// Make sure we only collect and send the UI data if it has been edited
if ( hasUiBeenEdited() ) { if ( hasUiBeenEdited() ) {
let data = let data =
{ {
@@ -520,10 +600,12 @@ function sendSaveData()
safezone: safezone safezone: safezone
} }
// Send the data
sendData( "saveUiData", data ); sendData( "saveUiData", data );
} }
} }
// Loads the UI settings
function loadUiSettings( data ) function loadUiSettings( data )
{ {
// Iterate through "remote", "radar" and "plateReader" // Iterate through "remote", "radar" and "plateReader"
@@ -550,20 +632,28 @@ function loadUiSettings( data )
elements.safezoneSlider.trigger( "input" ); elements.safezoneSlider.trigger( "input" );
} }
// Sets the on click function for the set BOLO plate button
elements.setBoloBtn.click( function() { elements.setBoloBtn.click( function() {
// Grab the value of the text input box
let plate = elements.boloText.val(); let plate = elements.boloText.val();
// Send the plate to the Lua side
sendData( "setBoloPlate", plate ); sendData( "setBoloPlate", plate );
} ) } )
// Checks what the user is typing into the plate box
function checkPlateInput( event ) function checkPlateInput( event )
{ {
let valid = /[A-Z0-9"?!£$%^&*()+\=\-_\[\]\{\};:'@#~,<.>/?|\\ ]/g.test( event.key ); // See if what has been typed is a valid key, GTA only seems to like A-Z and 0-9
let valid = /[a-zA-Z0-9 ]/g.test( event.key );
// If the key is not valid, prevent the key from being input into the box
if ( !valid ) { if ( !valid ) {
event.preventDefault(); event.preventDefault();
} }
} }
// Sets the src of the in-game help element, when true it loads the manual, when false it blanks the element
function loadHelp( state ) function loadHelp( state )
{ {
if ( state ) { if ( state ) {
@@ -576,6 +666,9 @@ function loadHelp( state )
/*------------------------------------------------------------------------------------ /*------------------------------------------------------------------------------------
UI scaling and positioning UI scaling and positioning
This whole bit could most likely be streamlined and made more efficient, it
works for now though. Redo it at a later date.
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
var remoteScale = 1.0; var remoteScale = 1.0;
var remoteMoving = false; var remoteMoving = false;
@@ -794,7 +887,7 @@ function clamp( num, min, max )
------------------------------------------------------------------------------------*/ ------------------------------------------------------------------------------------*/
// This runs when the JS file is loaded, loops through all of the remote buttons and assigns them an onclick function // This runs when the JS file is loaded, loops through all of the remote buttons and assigns them an onclick function
// elements.remote.find( "button" ).each( function( i, obj ) { // elements.remote.find( "button" ).each( function( i, obj ) {
$( "body" ).find( "button" ).each( function( i, obj ) { $( "body" ).find( "button, div" ).each( function( i, obj ) {
if ( $( this ).attr( "data-nuitype" ) ) { if ( $( this ).attr( "data-nuitype" ) ) {
$( this ).click( function() { $( this ).click( function() {
let type = $( this ).data( "nuitype" ); let type = $( this ).data( "nuitype" );

View File

@@ -82,16 +82,21 @@ function DATASAVE:GetIdentifier( src )
return nil return nil
end end
-- -- If we find the identifier type set in DATASAVE.idType, then we have the identifier
if ( string.find( id, self.idType, 1 ) ) then if ( string.find( id, self.idType, 1 ) ) then
-- Split the identifier so we just get the actual identifier
local split = self:SplitString( id, ":" ) local split = self:SplitString( id, ":" )
-- Return the identifier
return split[2] return split[2]
end end
end end
-- In the event we get nothing, return nil
return nil return nil
end end
-- Your typical split string function!
function DATASAVE:SplitString( inputstr, sep ) function DATASAVE:SplitString( inputstr, sep )
if ( sep == nil ) then if ( sep == nil ) then
sep = "%s" sep = "%s"
@@ -108,10 +113,12 @@ function DATASAVE:SplitString( inputstr, sep )
return t return t
end end
-- Prints the given message with the resource name attached
function DATASAVE:Print( msg ) function DATASAVE:Print( msg )
print( "^3[wk_wars2x] ^0" .. msg .. "^0" ) print( "^3[wk_wars2x] ^0" .. msg .. "^0" )
end end
-- Serverside event for saving a player's UI data
RegisterServerEvent( "wk:saveUiData" ) RegisterServerEvent( "wk:saveUiData" )
AddEventHandler( "wk:saveUiData", function( data ) AddEventHandler( "wk:saveUiData", function( data )
-- Check to make sure that the data being sent by the client is valid -- Check to make sure that the data being sent by the client is valid
@@ -121,17 +128,23 @@ AddEventHandler( "wk:saveUiData", function( data )
if ( valid ) then if ( valid ) then
DATASAVE:SavePlayerData( source, data ) DATASAVE:SavePlayerData( source, data )
else else
-- Print a message to the console saying the data sent by the client is not valid, this should rarely occur but it could be because
-- the client has modified the data being sent (mods/injections)
DATASAVE:Print( "^1Save data being sent from " .. GetPlayerName( source ) .. " (ID: " .. source .. ") is not valid, either something went wrong, or the player has modified the data being sent." ) DATASAVE:Print( "^1Save data being sent from " .. GetPlayerName( source ) .. " (ID: " .. source .. ") is not valid, either something went wrong, or the player has modified the data being sent." )
end end
end ) end )
-- Serverside event for when the player loads in and the system needs to get their saved UI data
RegisterServerEvent( "wk:getUiData" ) RegisterServerEvent( "wk:getUiData" )
AddEventHandler( "wk:getUiData", function() AddEventHandler( "wk:getUiData", function()
-- Try and get the player's data
local data = DATASAVE:GetPlayerData( source ) local data = DATASAVE:GetPlayerData( source )
-- Send the client the data if we get any
if ( data ) then if ( data ) then
TriggerClientEvent( "wk:loadUiData", source, data ) TriggerClientEvent( "wk:loadUiData", source, data )
else else
-- When player's first use the radar, they won't have saved UI data
DATASAVE:Print( "Player " .. GetPlayerName( source ) .. " (ID: " .. source .. ") doesn't have a UI settings file." ) DATASAVE:Print( "Player " .. GetPlayerName( source ) .. " (ID: " .. source .. ") doesn't have a UI settings file." )
end end
end ) end )

View File

@@ -5,6 +5,7 @@
-----------------------------------------------------------------------]]-- -----------------------------------------------------------------------]]--
-- Branding!
local label = local label =
[[ [[
// //
@@ -13,25 +14,38 @@ local label =
|| \ \ /\ / / __ __ _ _| |_| |__ / \ | |__) | (___ ) |\ V / || \ \ /\ / / __ __ _ _| |_| |__ / \ | |__) | (___ ) |\ V /
|| \ \/ \/ / '__/ _` | | __| '_ \ / /\ \ | _ / \___ \ / / > < || \ \/ \/ / '__/ _` | | __| '_ \ / /\ \ | _ / \___ \ / / > <
|| \ /\ /| | | (_| | | |_| | | | / ____ \| | \ \ ____) | / /_ / . \ || \ /\ /| | | (_| | | |_| | | | / ____ \| | \ \ ____) | / /_ / . \
|| \/ \/ |_| \__,_|_|\__|_| |_| /_/ \_\_| \_\_____/ |____/_/ \_\]] || \/ \/ |_| \__,_|_|\__|_| |_| /_/ \_\_| \_\_____/ |____/_/ \_\
||]]
-- Returns the current version set in fxmanifest.lua
function GetCurrentVersion() function GetCurrentVersion()
return GetResourceMetadata( GetCurrentResourceName(), "version" ) 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 ) PerformHttpRequest( "https://wolfknight98.github.io/wk_wars2x_web/version.txt", function( err, text, headers )
-- Wait to reduce spam
Citizen.Wait( 2000 ) Citizen.Wait( 2000 )
-- Print the branding!
print( label ) print( label )
-- Get the current resource version
local curVer = GetCurrentVersion() local curVer = GetCurrentVersion()
print( " ||\n || Current version: " .. curVer ) if ( text ~= nil ) then
-- Print out the current and latest version
print( " || Current version: " .. curVer )
print( " || Latest version: " .. text .."\n ||" ) print( " || Latest version: " .. text .."\n ||" )
-- If the versions are different, print it out
if ( text ~= curVer ) then 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" ) print( " || ^1Your Wraith ARS 2X version is outdated, visit the FiveM forum post to get the latest version.\n^0 \\\\\n" )
else else
print( " || ^2Wraith ARS 2X is up to date!\n^0 ||\n \\\\\n" ) print( " || ^2Wraith ARS 2X is up to date!\n^0 ||\n \\\\\n" )
end end
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 ) end )