mirror of
https://github.com/Michatec/wk_wars2x.git
synced 2026-04-01 00:16:27 +02:00
Merge pull request #16 from WolfKnight98/passenger-control
1.3.0 - Passenger control update
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
saves/*.json
|
||||
saves/*.json
|
||||
.vscode/settings.json
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
|
||||
82
README.md
82
README.md
@@ -25,23 +25,39 @@ Although these can be viewed ingame through the operator manual, the default key
|
||||
All of the configuration for the Wraith ARS 2X is done inside the `config.lua` file, below is a copy of the configuration file. All of the options have comments to describe what they do, along with the available options you can set. You have the ability to change the key binds for the large and small key set, the default operator menu options, and the default UI element scale and safezone.
|
||||
```lua
|
||||
-- Radar fast limit locking
|
||||
-- When enabled, the player will be able to define a fast limit within the radar's menu, when a vehicle
|
||||
-- When enabled, the player will be able to define a fast limit within the radar's menu, when a vehicle
|
||||
-- exceeds the fast limit, it will be locked into the fast box. Default setting is disabled to maintain realism
|
||||
CONFIG.allow_fast_limit = false
|
||||
CONFIG.allow_fast_limit = true
|
||||
|
||||
-- Radar only lock players with auto fast locking
|
||||
-- When enabled, the radar will only automatically lock a speed if the caught vehicle has a real player in it.
|
||||
CONFIG.only_lock_players = false
|
||||
|
||||
-- In-game first time quick start video
|
||||
-- When enabled, the player will be asked if they'd like to view the quick start video the first time they
|
||||
-- open the remote.
|
||||
CONFIG.allow_quick_start_video = true
|
||||
-- When enabled, the player will be asked if they'd like to view the quick start video the first time they
|
||||
-- open the remote.
|
||||
CONFIG.allow_quick_start_video = true
|
||||
|
||||
-- Allow passenger view
|
||||
-- When enabled, the front seat passenger will be able to view the radar and plate reader from their end.
|
||||
CONFIG.allow_passenger_view = true
|
||||
|
||||
-- Allow passenger control
|
||||
-- Dependent on CONFIG.allow_passenger_view. When enabled, the front seat passenger will be able to open the
|
||||
-- radar remote and control the radar and plate reader for themself and the driver.
|
||||
CONFIG.allow_passenger_control = true
|
||||
|
||||
-- Set this to true if you use Sonoran CAD with the WraithV2 plugin
|
||||
CONFIG.use_sonorancad = false
|
||||
|
||||
-- Sets the defaults of all keybinds
|
||||
-- These keybinds can be changed by each person in their GTA Settings->Keybinds->FiveM
|
||||
CONFIG.keyDefaults =
|
||||
{
|
||||
-- Remote control key
|
||||
-- Remote control key
|
||||
remote_control = "f5",
|
||||
|
||||
-- Radar key lock key
|
||||
-- Radar key lock key
|
||||
key_lock = "l",
|
||||
|
||||
-- Radar front antenna lock/unlock Key
|
||||
@@ -58,33 +74,41 @@ CONFIG.keyDefaults =
|
||||
}
|
||||
|
||||
-- Here you can change the default values for the operator menu, do note, if any of these values are not
|
||||
-- one of the options listed, the script will not work.
|
||||
CONFIG.menuDefaults =
|
||||
-- one of the options listed, the script will not work.
|
||||
CONFIG.menuDefaults =
|
||||
{
|
||||
-- Should the system calculate and display faster targets
|
||||
-- Options: true or false
|
||||
["fastDisplay"] = true,
|
||||
["fastDisplay"] = true,
|
||||
|
||||
-- Sensitivity for each radar mode, this changes how far the antennas will detect vehicles
|
||||
-- Options: 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["same"] = 0.6,
|
||||
["opp"] = 0.6,
|
||||
["same"] = 0.6,
|
||||
["opp"] = 0.6,
|
||||
|
||||
-- The volume of the audible beep
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
-- The volume of the audible beep
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["beep"] = 0.6,
|
||||
|
||||
-- The volume of the verbal lock confirmation
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
|
||||
-- The volume of the verbal lock confirmation
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["voice"] = 0.6,
|
||||
|
||||
-- The volume of the plate reader audio
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["plateAudio"] = 0.6,
|
||||
|
||||
-- The volume of the plate reader audio
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["plateAudio"] = 0.6,
|
||||
|
||||
-- The speed unit used in conversions
|
||||
-- Options: mph or kmh
|
||||
["speedType"] = "mph"
|
||||
-- Options: mph or kmh
|
||||
["speedType"] = "mph",
|
||||
|
||||
-- The state for automatic speed locking. This requires CONFIG.allow_fast_limit to be true.
|
||||
-- Options: true or false
|
||||
["fastLock"] = false,
|
||||
|
||||
-- The speed limit required for automatic speed locking. This requires CONFIG.allow_fast_limit to be true.
|
||||
-- Options: 0 to 200
|
||||
["fastLimit"] = 60
|
||||
}
|
||||
|
||||
-- Here you can change the default scale of the UI elements, as well as the safezone size
|
||||
@@ -94,14 +118,14 @@ CONFIG.uiDefaults =
|
||||
-- Options: 0.25 - 2.5
|
||||
scale =
|
||||
{
|
||||
radar = 1.0,
|
||||
remote = 1.0,
|
||||
plateReader = 1.0
|
||||
},
|
||||
radar = 0.75,
|
||||
remote = 0.75,
|
||||
plateReader = 0.75
|
||||
},
|
||||
|
||||
-- The safezone size, must be a multiple of 5.
|
||||
-- Options: 0 - 100
|
||||
safezone = 20
|
||||
safezone = 20
|
||||
}
|
||||
```
|
||||
|
||||
@@ -109,4 +133,4 @@ CONFIG.uiDefaults =
|
||||
If there is an improvement that you think should be made, open a pull request with your modified code, I will then review your request and either accept/deny it. Code in a pull request should be well formatted and commented, it will make it much easier for others to read and understand. In the event that you want to suggest something, but don't know how to code, open an issue with the enhancement tag and then fully describe your suggestion.
|
||||
|
||||
## Reporting issues/bugs
|
||||
Open an issue if you encounter any problems with the resource, if applicable, try to include detailed information on the issue and how to reproduce it. This will make it much easier to find and fix.
|
||||
Open an issue if you encounter any problems with the resource, if applicable, try to include detailed information on the issue and how to reproduce it. This will make it much easier to find and fix.
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
Wraith ARS 2X
|
||||
Created by WolfKnight
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -36,163 +36,203 @@ READER = {}
|
||||
Plate reader variables
|
||||
|
||||
NOTE - This is not a config, do not touch anything unless you know what
|
||||
you are actually doing.
|
||||
you are actually doing.
|
||||
----------------------------------------------------------------------------------]]--
|
||||
READER.vars =
|
||||
READER.vars =
|
||||
{
|
||||
-- Whether or not the plate reader's UI is visible
|
||||
-- Whether or not the plate reader's UI is visible
|
||||
displayed = false,
|
||||
|
||||
-- Whether or not the plate reader should be hidden, e.g. the display is active but the player then steps
|
||||
-- out of their vehicle
|
||||
hidden = false,
|
||||
|
||||
-- The BOLO plate
|
||||
boloPlate = "",
|
||||
|
||||
-- Cameras, this table contains all of the data needed for operation of the front and rear plate reader
|
||||
-- The BOLO plate
|
||||
boloPlate = "",
|
||||
|
||||
-- Cameras, this table contains all of the data needed for operation of the front and rear plate reader
|
||||
cams = {
|
||||
-- Variables for the front camera
|
||||
["front"] = {
|
||||
plate = "", -- The current plate caught by the reader
|
||||
index = "", -- The index of the current plate
|
||||
locked = false -- If the reader is locked
|
||||
},
|
||||
locked = false -- If the reader is locked
|
||||
},
|
||||
|
||||
-- Variables for the rear camera
|
||||
["rear"] = {
|
||||
plate = "", -- The current plate caught by the reader
|
||||
index = "", -- The index of the current plate
|
||||
locked = false -- If the reader is locked
|
||||
locked = false -- If the reader is locked
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Plate reader functions
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- Gets the display state
|
||||
function READER:GetDisplayState()
|
||||
return self.vars.displayed
|
||||
end
|
||||
end
|
||||
|
||||
-- Toggles the display state of the plate reader system
|
||||
function READER:ToggleDisplayState()
|
||||
-- Toggle the display variable
|
||||
self.vars.displayed = not self.vars.displayed
|
||||
-- Toggle the display variable
|
||||
self.vars.displayed = not self.vars.displayed
|
||||
|
||||
-- Send the toggle message to the NUI side
|
||||
-- Send the toggle message to the NUI side
|
||||
SendNUIMessage( { _type = "setReaderDisplayState", state = self:GetDisplayState() } )
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
||||
-- Returns the stored plate for the given reader
|
||||
function READER:GetPlate( cam )
|
||||
return self.vars.cams[cam].plate
|
||||
end
|
||||
-- Getter and setter for the display hidden state
|
||||
function READER:GetDisplayHidden() return self.vars.hidden end
|
||||
function READER:SetDisplayHidden( state ) self.vars.hidden = state end
|
||||
|
||||
-- Sets the plate for the given reader to the given plate
|
||||
function READER:SetPlate( cam, plate )
|
||||
self.vars.cams[cam].plate = plate
|
||||
end
|
||||
-- Getter and setter for the given camera's plate
|
||||
function READER:GetPlate( cam ) return self.vars.cams[cam].plate end
|
||||
function READER:SetPlate( cam, 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
|
||||
end
|
||||
|
||||
-- Sets the plate index for the given reader to the given index
|
||||
function READER:SetIndex( cam, index )
|
||||
self.vars.cams[cam].index = index
|
||||
end
|
||||
-- Getter and setter for the given camera's plate display index
|
||||
function READER:GetIndex( cam ) return self.vars.cams[cam].index end
|
||||
function READER:SetIndex( cam, index ) self.vars.cams[cam].index = index end
|
||||
|
||||
-- Returns the bolo plate
|
||||
function READER:GetBoloPlate()
|
||||
return self.vars.boloPlate
|
||||
end
|
||||
if ( self.vars.boloPlate ~= nil ) then
|
||||
return self.vars.boloPlate
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets the bolo plate to the given plate
|
||||
-- Sets the bolo plate to the given plate
|
||||
function READER:SetBoloPlate( plate )
|
||||
self.vars.boloPlate = plate
|
||||
UTIL:Notify( "BOLO plate set to: " .. plate )
|
||||
end
|
||||
UTIL:Notify( "BOLO plate set to: ~b~" .. plate )
|
||||
end
|
||||
|
||||
-- Clears the BOLO plate
|
||||
function READER:ClearBoloPlate()
|
||||
self.vars.boloPlate = nil
|
||||
UTIL:Notify( "~b~BOLO plate cleared!" )
|
||||
end
|
||||
|
||||
-- Returns if the given reader is locked
|
||||
function READER:GetCamLocked( cam )
|
||||
return self.vars.cams[cam].locked
|
||||
end
|
||||
function READER:GetCamLocked( cam ) return self.vars.cams[cam].locked 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
|
||||
-- Toggle the lock state
|
||||
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] )
|
||||
|
||||
-- Play a beep
|
||||
if ( self:GetCamLocked( cam ) ) then
|
||||
if ( playBeep ) then
|
||||
self:ForceNUIUpdate( false )
|
||||
end
|
||||
|
||||
if ( playBeep ) then
|
||||
SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "plateAudio" ) } )
|
||||
end
|
||||
end
|
||||
|
||||
if ( isBolo ) then
|
||||
if ( isBolo ) then
|
||||
SendNUIMessage( { _type = "audio", name = "plate_hit", vol = RADAR:GetSettingValue( "plateAudio" ) } )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Trigger an event so developers can hook into the scanner every time a plate is locked
|
||||
TriggerServerEvent( "wk:onPlateLocked", cam, self:GetPlate( cam ), self:GetIndex( cam ) )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Tell the NUI side to show/hide the lock icon
|
||||
SendNUIMessage( { _type = "lockPlate", cam = cam, state = self:GetCamLocked( cam ), isBolo = isBolo } )
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns if the plate reader system can perform tasks
|
||||
function READER:CanPerformMainTask()
|
||||
return self.vars.displayed and not self.vars.hidden
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns if the given relative position value is for front or rear
|
||||
-- Returns if the given relative position value is for front or rear
|
||||
function READER:GetCamFromNum( relPos )
|
||||
if ( relPos == 1 ) then
|
||||
if ( relPos == 1 ) then
|
||||
return "front"
|
||||
elseif ( relPos == -1 ) then
|
||||
elseif ( relPos == -1 ) then
|
||||
return "rear"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- 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 )
|
||||
end )
|
||||
|
||||
-- Runs when the "Toggle Display" button is pressed on the plate reder box
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Plate reader NUI callbacks
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- Runs when the "Toggle Display" button is pressed on the plate reder box
|
||||
RegisterNUICallback( "togglePlateReaderDisplay", function( data, cb )
|
||||
-- Toggle the display state
|
||||
-- Toggle the display state
|
||||
READER:ToggleDisplayState()
|
||||
cb('ok')
|
||||
cb( "ok" )
|
||||
end )
|
||||
|
||||
-- Runs when the "Set BOLO Plate" button is pressed on the plate reader box
|
||||
RegisterNUICallback( "setBoloPlate", function( plate, cb )
|
||||
-- Set the BOLO plate
|
||||
-- Set the BOLO plate
|
||||
READER:SetBoloPlate( plate )
|
||||
cb('ok')
|
||||
cb( "ok" )
|
||||
end )
|
||||
|
||||
-- Runs when the "Clear BOLO Plate" button is pressed on the plate reader box
|
||||
RegisterNUICallback( "clearBoloPlate", function( plate, cb )
|
||||
-- Clear the BOLO plate
|
||||
READER:ClearBoloPlate()
|
||||
cb( "ok" )
|
||||
end )
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Plate reader threads
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- This is the main function that runs and scans all vehicles in front and behind the patrol vehicle
|
||||
function READER:Main()
|
||||
-- Check that the system can actually run
|
||||
if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then
|
||||
-- Check that the system can actually run
|
||||
if ( PLY:VehicleStateValid() and self:CanPerformMainTask() ) then
|
||||
-- Loop through front (1) and rear (-1)
|
||||
for i = 1, -1, -2 do
|
||||
for i = 1, -1, -2 do
|
||||
-- Get the world position of the player's vehicle
|
||||
local pos = GetEntityCoords( PLY.veh )
|
||||
|
||||
@@ -202,14 +242,14 @@ function READER:Main()
|
||||
-- Get the end position 50m in front/behind the player's vehicle
|
||||
local offset = GetOffsetFromEntityInWorldCoords( PLY.veh, -2.5, ( 50.0 * i ), 0.0 )
|
||||
|
||||
-- Run the ray trace to get a vehicle
|
||||
-- Run the ray trace to get a vehicle
|
||||
local veh = UTIL:GetVehicleInDirection( PLY.veh, start, offset )
|
||||
|
||||
-- Get the plate reader text for front/rear
|
||||
local cam = self:GetCamFromNum( i )
|
||||
|
||||
|
||||
-- Only proceed to read a plate if the hit entity is a valid vehicle and the current camera isn't locked
|
||||
if ( DoesEntityExist( veh ) and IsEntityAVehicle( veh ) and not self:GetCamLocked( cam ) ) then
|
||||
if ( DoesEntityExist( veh ) and IsEntityAVehicle( veh ) and not self:GetCamLocked( cam ) ) then
|
||||
-- Get the heading of the player's vehicle and the hit vehicle
|
||||
local ownH = UTIL:Round( GetEntityHeading( PLY.veh ), 0 )
|
||||
local tarH = UTIL:Round( GetEntityHeading( veh ), 0 )
|
||||
@@ -218,16 +258,16 @@ function READER:Main()
|
||||
local dir = UTIL:GetEntityRelativeDirection( ownH, tarH )
|
||||
|
||||
-- Only run the rest of the plate check code if we can see the front or rear of the vehicle
|
||||
if ( dir > 0 ) then
|
||||
-- Get the licence plate text from the vehicle
|
||||
if ( dir > 0 ) then
|
||||
-- Get the licence plate text from the vehicle
|
||||
local plate = GetVehicleNumberPlateText( veh )
|
||||
|
||||
-- Get the licence plate index from the vehicle
|
||||
-- Get the licence plate index from the vehicle
|
||||
local index = GetVehicleNumberPlateTextIndex( veh )
|
||||
|
||||
-- Only update the stored plate if it's different, otherwise we'd keep sending a NUI message to update the displayed
|
||||
-- plate and image even though they're the same
|
||||
if ( self:GetPlate( cam ) ~= plate ) then
|
||||
-- plate and image even though they're the same
|
||||
if ( self:GetPlate( cam ) ~= plate ) then
|
||||
-- Set the plate for the current reader
|
||||
self:SetPlate( cam, plate )
|
||||
|
||||
@@ -235,21 +275,26 @@ function READER:Main()
|
||||
self:SetIndex( cam, index )
|
||||
|
||||
-- Automatically lock the plate if the scanned plate matches the BOLO
|
||||
if ( plate == self:GetBoloPlate() ) then
|
||||
if ( plate == self:GetBoloPlate() ) then
|
||||
self:LockCam( cam, false, true )
|
||||
end
|
||||
|
||||
SYNC:LockReaderCam( cam, READER:GetCameraDataPacket( cam ) )
|
||||
end
|
||||
|
||||
-- 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 every time a plate is scanned
|
||||
TriggerServerEvent( "wk:onPlateScanned", cam, plate, index )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- If we use Sonoran CAD, reduce the plate events to just player's vehicle, otherwise life as normal
|
||||
if ( ( CONFIG.use_sonorancad and ( UTIL:IsPlayerInVeh( veh ) or IsVehiclePreviouslyOwnedByPlayer( veh ) ) and GetVehicleClass( veh ) ~= 18 ) or not CONFIG.use_sonorancad ) then
|
||||
-- Trigger the event so developers can hook into the scanner every time a plate is scanned
|
||||
TriggerServerEvent( "wk:onPlateScanned", cam, plate, index )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Main thread
|
||||
Citizen.CreateThread( function()
|
||||
@@ -259,31 +304,31 @@ Citizen.CreateThread( function()
|
||||
|
||||
-- Wait half a second
|
||||
Citizen.Wait( 500 )
|
||||
end
|
||||
end
|
||||
end )
|
||||
|
||||
-- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not
|
||||
-- using it. Hides the radar UI when certain criteria is met, e.g. in pause menu or stepped out ot the
|
||||
-- patrol vehicle
|
||||
-- This function is pretty much straight from WraithRS, it does the job so I didn't see the point in not
|
||||
-- using it. Hides the radar UI when certain criteria is met, e.g. in pause menu or stepped out ot the
|
||||
-- patrol vehicle
|
||||
function READER:RunDisplayValidationCheck()
|
||||
if ( ( ( PLY.veh == 0 or ( PLY.veh > 0 and not PLY.vehClassValid ) ) and self:GetDisplayState() and not self:GetDisplayHidden() ) or IsPauseMenuActive() and self:GetDisplayState() ) then
|
||||
self:SetDisplayHidden( true )
|
||||
self:SetDisplayHidden( true )
|
||||
SendNUIMessage( { _type = "setReaderDisplayState", state = false } )
|
||||
elseif ( PLY.veh > 0 and PLY.vehClassValid and PLY.inDriverSeat and self:GetDisplayState() and self:GetDisplayHidden() ) then
|
||||
self:SetDisplayHidden( false )
|
||||
elseif ( PLY:CanViewRadar() and self:GetDisplayState() and self:GetDisplayHidden() ) then
|
||||
self:SetDisplayHidden( false )
|
||||
SendNUIMessage( { _type = "setReaderDisplayState", state = true } )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Runs the display validation check for the radar
|
||||
Citizen.CreateThread( function()
|
||||
Citizen.CreateThread( function()
|
||||
Citizen.Wait( 100 )
|
||||
|
||||
while ( true ) do
|
||||
-- Run the check
|
||||
while ( true ) do
|
||||
-- Run the check
|
||||
READER:RunDisplayValidationCheck()
|
||||
|
||||
-- Wait half a second
|
||||
-- Wait half a second
|
||||
Citizen.Wait( 500 )
|
||||
end
|
||||
end
|
||||
end )
|
||||
136
cl_player.lua
Normal file
136
cl_player.lua
Normal file
@@ -0,0 +1,136 @@
|
||||
--[[---------------------------------------------------------------------------------------
|
||||
|
||||
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-2021 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.
|
||||
|
||||
---------------------------------------------------------------------------------------]]--
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Player info variables
|
||||
----------------------------------------------------------------------------------]]--
|
||||
PLY =
|
||||
{
|
||||
ped = PlayerPedId(),
|
||||
veh = nil,
|
||||
inDriverSeat = false,
|
||||
inPassengerSeat = false,
|
||||
vehClassValid = false
|
||||
}
|
||||
|
||||
-- Returns if the current vehicle fits the validity requirements for the radar to work
|
||||
function PLY:VehicleStateValid()
|
||||
return DoesEntityExist( self.veh ) and self.veh > 0 and self.vehClassValid
|
||||
end
|
||||
|
||||
-- Used to check if the player is in a position where the radar should be allowed operation
|
||||
function PLY:IsDriver()
|
||||
return self:VehicleStateValid() and self.inDriverSeat
|
||||
end
|
||||
|
||||
-- Returns if the player is in the front passenger seat of an emergency vehicle
|
||||
function PLY:IsPassenger()
|
||||
return self:VehicleStateValid() and self.inPassengerSeat
|
||||
end
|
||||
|
||||
-- Returns if the player can view the radar, ensures their vehicle state is valid and that they are a driver or
|
||||
-- a passenger (where valid)
|
||||
function PLY:CanViewRadar()
|
||||
return self:IsDriver() or ( self:IsPassenger() and RADAR:IsPassengerViewAllowed() )
|
||||
end
|
||||
|
||||
-- Returns if the player is allowed to control the radar from the passenger seat
|
||||
function PLY:CanControlRadar()
|
||||
return self:IsDriver() or ( self:IsPassenger() and RADAR:IsPassengerControlAllowed() )
|
||||
end
|
||||
|
||||
-- Returns the ped in the opposite seat to the player, e.g. if we're the passenger, then return the driver
|
||||
function PLY:GetOtherPed()
|
||||
if ( self:IsDriver() ) then
|
||||
return GetPedInVehicleSeat( PLY.veh, 0 )
|
||||
elseif ( self:IsPassenger() ) then
|
||||
return GetPedInVehicleSeat( PLY.veh, -1 )
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Returns the server ID of the player in the opposite seat (driver/passenger)
|
||||
function PLY:GetOtherPedServerId()
|
||||
local otherPed = self:GetOtherPed()
|
||||
|
||||
if ( otherPed ~= nil and otherPed ~= 0 and IsPedAPlayer( otherPed ) ) then
|
||||
local otherPly = GetPlayerServerId( NetworkGetPlayerIndexFromPed( otherPed ) )
|
||||
|
||||
return otherPly
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
-- The main purpose of this thread is to update the information about the local player, including their
|
||||
-- ped id, the vehicle id (if they're in one), whether they're in a driver seat, and if the vehicle's class
|
||||
-- is valid or not
|
||||
Citizen.CreateThread( function()
|
||||
while ( true ) do
|
||||
PLY.ped = PlayerPedId()
|
||||
PLY.veh = GetVehiclePedIsIn( PLY.ped, false )
|
||||
PLY.inDriverSeat = GetPedInVehicleSeat( PLY.veh, -1 ) == PLY.ped
|
||||
PLY.inPassengerSeat = GetPedInVehicleSeat( PLY.veh, 0 ) == PLY.ped
|
||||
PLY.vehClassValid = GetVehicleClass( PLY.veh ) == 18
|
||||
|
||||
Citizen.Wait( 500 )
|
||||
end
|
||||
end )
|
||||
|
||||
-- This thread is used to check when the player is entering a vehicle and then triggers the sync system
|
||||
Citizen.CreateThread( function()
|
||||
while ( true ) do
|
||||
-- The sync trigger should only start when the player is getting into a vehicle
|
||||
if ( IsPedGettingIntoAVehicle( PLY.ped ) and RADAR:IsPassengerViewAllowed() ) then
|
||||
-- Get the vehicle the player is entering
|
||||
local vehEntering = GetVehiclePedIsEntering( PLY.ped )
|
||||
|
||||
-- Only proceed if the vehicle the player is entering is an emergency vehicle
|
||||
if ( GetVehicleClass( vehEntering ) == 18 ) then
|
||||
-- Wait two seconds, this gives enough time for the player to get sat in the seat
|
||||
Citizen.Wait( 2000 )
|
||||
|
||||
-- Get the vehicle the player is now in
|
||||
local veh = GetVehiclePedIsIn( PLY.ped, false )
|
||||
|
||||
-- Trigger the main sync data function if the vehicle the player is now in is the same as the one they
|
||||
-- began entering
|
||||
if ( veh == vehEntering ) then
|
||||
SYNC:SyncDataOnEnter()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Citizen.Wait( 500 )
|
||||
end
|
||||
end )
|
||||
1807
cl_radar.lua
1807
cl_radar.lua
File diff suppressed because it is too large
Load Diff
437
cl_sync.lua
Normal file
437
cl_sync.lua
Normal file
@@ -0,0 +1,437 @@
|
||||
--[[---------------------------------------------------------------------------------------
|
||||
|
||||
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-2021 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.
|
||||
|
||||
---------------------------------------------------------------------------------------]]--
|
||||
|
||||
-- Register the decorator used to tell if the other player has the remote open
|
||||
DecorRegister( "wk_wars2x_sync_remoteOpen", 2 )
|
||||
|
||||
-- Takes the given backup functions and restores the data
|
||||
local function RestoreData( obj, getFunc, setFunc, setBackupFunc, key )
|
||||
if ( key ~= nil ) then
|
||||
local data = getFunc( obj, key )
|
||||
|
||||
if ( data ~= nil ) then
|
||||
setFunc( obj, key, data )
|
||||
setBackupFunc( obj, key, nil )
|
||||
end
|
||||
else
|
||||
local data = getFunc( obj )
|
||||
|
||||
if ( data ~= nil ) then
|
||||
setFunc( obj, data )
|
||||
setBackupFunc( obj, nil )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Plate reader sync variables and functions
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- Declares a table that is used to backup the player's plate reader data
|
||||
READER.backupData =
|
||||
{
|
||||
cams = {
|
||||
["front"] = nil,
|
||||
["rear"] = nil
|
||||
}
|
||||
}
|
||||
|
||||
-- Returns a table with the front and rear plate reader data
|
||||
function READER:GetReaderDataForSync()
|
||||
return {
|
||||
["front"] = self.vars.cams["front"],
|
||||
["rear"] = self.vars.cams["rear"]
|
||||
}
|
||||
end
|
||||
|
||||
-- Sets the internal plate reader data for the given camera
|
||||
function READER:SetReaderCamData( cam, data )
|
||||
if ( type( data ) == "table" ) then
|
||||
self.vars.cams[cam] = data
|
||||
end
|
||||
end
|
||||
|
||||
-- Getter and setter for the backup plate reader data
|
||||
function READER:GetBackupReaderData( cam ) return self.backupData.cams[cam] end
|
||||
function READER:SetBackupReaderData( cam, data ) self.backupData.cams[cam] = data end
|
||||
|
||||
-- Returns if there is any backup data for the plate reader
|
||||
function READER:IsThereBackupData()
|
||||
return self:GetBackupReaderData( "front" ) ~= nil or self:GetBackupReaderData( "rear" ) ~= nil
|
||||
end
|
||||
|
||||
-- Backs up the player's plate reader data
|
||||
function READER:BackupData()
|
||||
-- Get the player's data
|
||||
local data = self:GetReaderDataForSync()
|
||||
|
||||
-- Iterate through the front and rear camera
|
||||
for cam in UTIL:Values( { "front", "rear" } ) do
|
||||
-- Check that there isn't already backup data, then if not, back up the player's data
|
||||
if ( self:GetBackupReaderData( cam ) == nil ) then
|
||||
self:SetBackupReaderData( cam, data[cam] )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Replaces the internal plate reader data with the data provided
|
||||
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] )
|
||||
end
|
||||
|
||||
-- Force the NUI side to update the plate reader display with the new data
|
||||
self:ForceNUIUpdate( true )
|
||||
end )
|
||||
end
|
||||
|
||||
-- Restores the backed up plate reader data
|
||||
function READER:RestoreFromBackup()
|
||||
-- Iterate through the cameras and restore their backups
|
||||
for cam in UTIL:Values( { "front", "rear" } ) do
|
||||
RestoreData( READER, READER.GetBackupReaderData, READER.SetReaderCamData, READER.SetBackupReaderData, cam )
|
||||
end
|
||||
|
||||
-- Force the NUI side to update the plate reader display with the restored data
|
||||
self:ForceNUIUpdate( true )
|
||||
end
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Radar sync variables and functions
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- Declares a table that is used to backup the player's radar data
|
||||
RADAR.backupData = {
|
||||
power = nil,
|
||||
om = nil,
|
||||
antennas = {
|
||||
["front"] = nil,
|
||||
["rear"] = nil
|
||||
}
|
||||
}
|
||||
|
||||
-- Returns a table with the power state, operator meny, front and rear radar data
|
||||
function RADAR:GetRadarDataForSync()
|
||||
return {
|
||||
power = self.vars.power,
|
||||
om = self.vars.settings,
|
||||
["front"] = self.vars.antennas["front"],
|
||||
["rear"] = self.vars.antennas["rear"]
|
||||
}
|
||||
end
|
||||
|
||||
-- Returns the radar's internal operator menu settings table
|
||||
function RADAR:GetOMTableData() return self.vars.settings end
|
||||
|
||||
-- Sets the operator menu settings table within the radar's main variables table
|
||||
function RADAR:SetOMTableData( data )
|
||||
if ( type( data ) == "table" ) then
|
||||
self.vars.settings = data
|
||||
self:UpdateOptionIndexes( false )
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets the antenna settings table for the given antenna within the radar's main variables table
|
||||
function RADAR:SetAntennaTableData( ant, data )
|
||||
if ( type( data ) == "table" ) then
|
||||
self.vars.antennas[ant] = data
|
||||
end
|
||||
end
|
||||
|
||||
-- Getter and setter for the backup radar power state
|
||||
function RADAR:GetBackupPowerState() return self.backupData.power end
|
||||
function RADAR:SetBackupPowerState( state ) self.backupData.power = state end
|
||||
|
||||
-- Getter and setter for the backup radar operator menu data
|
||||
function RADAR:GetBackupOMData() return self.backupData.om end
|
||||
function RADAR:SetBackupOMData( data ) self.backupData.om = data end
|
||||
|
||||
-- Getter and setter for the backup radar antennas data
|
||||
function RADAR:GetBackupAntennaData( ant ) return self.backupData.antennas[ant] end
|
||||
function RADAR:SetBackupAntennaData( ant, data ) self.backupData.antennas[ant] = data end
|
||||
|
||||
-- Retuns if there is any backup radar data
|
||||
function RADAR:IsThereBackupData()
|
||||
return self:GetBackupOMData() ~= nil or self:GetBackupAntennaData( "front" ) ~= nil or self:GetBackupAntennaData( "rear" ) ~= nil
|
||||
end
|
||||
|
||||
-- Used when the player becomes a passenger in another vehicle. The local data is backed up to make way for the data
|
||||
-- provided by the driver. When the player becomes the driver again, the local data is restored.
|
||||
function RADAR:BackupData()
|
||||
local data = self:GetRadarDataForSync()
|
||||
|
||||
-- Backup the power state
|
||||
if ( self:GetBackupPowerState() == nil ) then
|
||||
self:SetBackupPowerState( data.power )
|
||||
end
|
||||
|
||||
-- Backup operator menu data
|
||||
if ( self:GetBackupOMData() == nil ) then
|
||||
self:SetBackupOMData( data.om )
|
||||
end
|
||||
|
||||
-- Only backup the radar data if the player has the power on. There's no point backing up the data as it'll just
|
||||
-- get reset when they turn the power on anyway
|
||||
if ( data.power ) then
|
||||
-- Backup front and rear antenna data
|
||||
for ant in UTIL:Values( { "front", "rear" } ) do
|
||||
if ( self:GetBackupAntennaData( ant ) == nil ) then
|
||||
self:SetBackupAntennaData( ant, data[ant] )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Backs up the local radar data and then replaces it with the data provided by the driver
|
||||
function RADAR: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 operator menu settings
|
||||
self:SetOMTableData( data.om )
|
||||
|
||||
-- Set the antenna data
|
||||
for ant in UTIL:Values( { "front", "rear" } ) do
|
||||
self:SetAntennaTableData( ant, data[ant] )
|
||||
end
|
||||
|
||||
-- Set the power state
|
||||
self:SetPowerState( data.power, true )
|
||||
|
||||
-- Update the display
|
||||
if ( data.power ) then
|
||||
self:SendSettingUpdate()
|
||||
end
|
||||
end )
|
||||
end
|
||||
|
||||
-- Restores the local player's operator menu and antenna data
|
||||
function RADAR:RestoreFromBackup()
|
||||
-- Restore the operator menu data
|
||||
RestoreData( RADAR, RADAR.GetBackupOMData, RADAR.SetOMTableData, RADAR.SetBackupOMData )
|
||||
|
||||
-- Iterate through the antennas and restore their backups
|
||||
for ant in UTIL:Values( { "front", "rear" } ) do
|
||||
RestoreData( RADAR, RADAR.GetBackupAntennaData, RADAR.SetAntennaTableData, RADAR.SetBackupAntennaData, ant )
|
||||
end
|
||||
|
||||
-- Get the power state
|
||||
local pwrState = self:GetBackupPowerState()
|
||||
|
||||
-- Restore the power state
|
||||
if ( pwrState ~= nil ) then
|
||||
self:SetPowerState( pwrState, true )
|
||||
self:SetBackupPowerState( nil )
|
||||
end
|
||||
|
||||
-- Update the display
|
||||
if ( pwrState ) then
|
||||
Citizen.SetTimeout( 50, function()
|
||||
self:SendSettingUpdate()
|
||||
end )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Sync variables
|
||||
----------------------------------------------------------------------------------]]--
|
||||
SYNC = {}
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Sync functions
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- Returns if the given player has the remote open
|
||||
function SYNC:IsRemoteAlreadyOpen( ply )
|
||||
if ( not RADAR:IsPassengerViewAllowed() ) then
|
||||
return false
|
||||
else
|
||||
return DecorGetBool( ply, "wk_wars2x_sync_remoteOpen" )
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets the remote open decor for the local player to the given state
|
||||
function SYNC:SetRemoteOpenState( state )
|
||||
if ( RADAR:IsPassengerViewAllowed() ) then
|
||||
DecorSetBool( PLY.ped, "wk_wars2x_sync_remoteOpen", state )
|
||||
end
|
||||
end
|
||||
|
||||
-- Used to get the other ped (driver/passenger) in a vehicle and calls the given callback. This function will only work
|
||||
-- if the player can control the radar, it also ensures that the other ped (if found) exists and is a player. The other
|
||||
-- player's server ID is passed to the given callback as an argument.
|
||||
function SYNC:SyncData( cb )
|
||||
if ( PLY:CanControlRadar() ) then
|
||||
local otherPly = PLY:GetOtherPedServerId()
|
||||
|
||||
if ( otherPly ~= nil ) then
|
||||
cb( otherPly )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Sends the radar's power state to the other player (driver/passenger)
|
||||
function SYNC:SendPowerState( state )
|
||||
self:SyncData( function( ply )
|
||||
TriggerServerEvent( "wk_wars2x_sync:sendPowerState", ply, state )
|
||||
end )
|
||||
end
|
||||
|
||||
-- Sends the power state for the given antenna to the other player (driver/passenger)
|
||||
function SYNC:SendAntennaPowerState( state, ant )
|
||||
self:SyncData( function( ply )
|
||||
TriggerServerEvent( "wk_wars2x_sync:sendAntennaPowerState", ply, state, ant )
|
||||
end )
|
||||
end
|
||||
|
||||
-- Sends the mode for the given antenna to the other player (driver/passenger)
|
||||
function SYNC:SendAntennaMode( ant, mode )
|
||||
self:SyncData( function( ply )
|
||||
TriggerServerEvent( "wk_wars2x_sync:sendAntennaMode", ply, ant, mode )
|
||||
end )
|
||||
end
|
||||
|
||||
-- Sends a lock/unlock state, as well as the current player's displayed data to the other player (driver/passenger)
|
||||
function SYNC:LockAntennaSpeed( ant, data )
|
||||
self:SyncData( function( ply )
|
||||
TriggerServerEvent( "wk_wars2x_sync:sendLockAntennaSpeed", ply, ant, data )
|
||||
end )
|
||||
end
|
||||
|
||||
-- Sends the given operator menu table data to the other player
|
||||
function SYNC:SendUpdatedOMData( data )
|
||||
self:SyncData( function( ply )
|
||||
TriggerServerEvent( "wk_wars2x_sync:sendUpdatedOMData", ply, data )
|
||||
end )
|
||||
end
|
||||
|
||||
-- Sends the plate reader lock event with the data from the reader that was locked
|
||||
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
|
||||
-- vehicle meets the requirements of what the radar requires. This way we don't have to do additional
|
||||
-- checks manually.
|
||||
if ( PLY:IsPassenger() ) then
|
||||
local driver = PLY:GetOtherPedServerId()
|
||||
|
||||
-- Only trigger the event if there is actually a driver
|
||||
if ( driver ~= nil ) then
|
||||
TriggerServerEvent( "wk_wars2x_sync:requestRadarData", driver )
|
||||
end
|
||||
elseif ( PLY:IsDriver() ) then
|
||||
if ( RADAR:IsThereBackupData() ) then
|
||||
-- Restore the local data
|
||||
RADAR:RestoreFromBackup()
|
||||
READER:RestoreFromBackup()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Sync client events
|
||||
----------------------------------------------------------------------------------]]--
|
||||
-- Event for receiving the radar powet state
|
||||
RegisterNetEvent( "wk_wars2x_sync:receivePowerState" )
|
||||
AddEventHandler( "wk_wars2x_sync:receivePowerState", function( state )
|
||||
-- Set the radar's power
|
||||
RADAR:SetPowerState( state, false )
|
||||
end )
|
||||
|
||||
-- Event for receiving a power state for the given antenna
|
||||
RegisterNetEvent( "wk_wars2x_sync:receiveAntennaPowerState" )
|
||||
AddEventHandler( "wk_wars2x_sync:receiveAntennaPowerState", function( state, antenna )
|
||||
-- Get the current local antenna power state
|
||||
local power = RADAR:IsAntennaTransmitting( antenna )
|
||||
|
||||
-- If the local power state is not the same as the given state, toggle the antenna's power
|
||||
if ( power ~= state ) then
|
||||
RADAR:ToggleAntenna( antenna )
|
||||
end
|
||||
end )
|
||||
|
||||
-- Event for receiving a mode for the given antenna
|
||||
RegisterNetEvent( "wk_wars2x_sync:receiveAntennaMode" )
|
||||
AddEventHandler( "wk_wars2x_sync:receiveAntennaMode", function( antenna, mode )
|
||||
RADAR:SetAntennaMode( antenna, mode )
|
||||
end )
|
||||
|
||||
-- Event for receiving a lock state and speed data for the given antenna
|
||||
RegisterNetEvent( "wk_wars2x_sync:receiveLockAntennaSpeed" )
|
||||
AddEventHandler( "wk_wars2x_sync:receiveLockAntennaSpeed", function( antenna, data )
|
||||
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 radarData = RADAR:GetRadarDataForSync()
|
||||
local readerData = READER:GetReaderDataForSync()
|
||||
|
||||
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[1] )
|
||||
READER:LoadDataFromDriver( data[2] )
|
||||
end )
|
||||
|
||||
-- Event for receiving updated operator menu data from another player
|
||||
RegisterNetEvent( "wk_wars2x_sync:receiveUpdatedOMData" )
|
||||
AddEventHandler( "wk_wars2x_sync:receiveUpdatedOMData", function( data )
|
||||
if ( PLY:IsDriver() or ( PLY:IsPassenger() and RADAR:IsThereBackupData() ) ) then
|
||||
RADAR:SetOMTableData( data )
|
||||
RADAR:SendSettingUpdate()
|
||||
end
|
||||
end )
|
||||
86
cl_utils.lua
86
cl_utils.lua
@@ -2,13 +2,13 @@
|
||||
|
||||
Wraith ARS 2X
|
||||
Created by WolfKnight
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -35,49 +35,49 @@ UTIL = {}
|
||||
-- Returns a number to a set number of decimal places
|
||||
function UTIL:Round( num, numDecimalPlaces )
|
||||
return tonumber( string.format( "%." .. ( numDecimalPlaces or 0 ) .. "f", num ) )
|
||||
end
|
||||
end
|
||||
|
||||
-- The custom font used for the digital displays have the ¦ symbol as an empty character, this function
|
||||
-- takes a speed and returns a formatted speed that can be displayed on the radar
|
||||
-- The custom font used for the digital displays have the ¦ symbol as an empty character, this function
|
||||
-- takes a speed and returns a formatted speed that can be displayed on the radar
|
||||
function UTIL:FormatSpeed( speed )
|
||||
-- Return "Err" (Error) if the given speed is outside the 0-999 range
|
||||
if ( speed < 0 or speed > 999 ) then return "Err" end
|
||||
-- Return "Err" (Error) if the given speed is outside the 0-999 range
|
||||
if ( speed < 0 or speed > 999 ) then return "Err" end
|
||||
|
||||
-- Convert the speed to a string
|
||||
-- Convert the speed to a string
|
||||
local text = tostring( speed )
|
||||
local pipes = ""
|
||||
|
||||
-- Create a string of pipes (¦) for the number of spaces
|
||||
for i = 1, 3 - string.len( text ) do
|
||||
for i = 1, 3 - string.len( text ) do
|
||||
pipes = pipes .. "¦"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Return the formatted speed
|
||||
return pipes .. text
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns a clamped numerical value based on the given parameters
|
||||
-- Returns a clamped numerical value based on the given parameters
|
||||
function UTIL:Clamp( val, min, max )
|
||||
-- Return the min value if the given value is less than the min
|
||||
if ( val < min ) then
|
||||
return min
|
||||
if ( val < min ) then
|
||||
return min
|
||||
-- Return the max value if the given value is larger than the max
|
||||
elseif ( val > max ) then
|
||||
return max
|
||||
end
|
||||
elseif ( val > max ) then
|
||||
return max
|
||||
end
|
||||
|
||||
-- Return the given value if it's between the min and max
|
||||
return val
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
-- Returns if the given table is empty, includes numerical and non-numerical key values
|
||||
function UTIL:IsTableEmpty( t )
|
||||
local c = 0
|
||||
local c = 0
|
||||
|
||||
for _ in pairs( t ) do c = c + 1 end
|
||||
for _ in pairs( t ) do c = c + 1 end
|
||||
|
||||
return c == 0
|
||||
end
|
||||
end
|
||||
|
||||
-- Credit to Deltanic for this function
|
||||
function UTIL:Values( xs )
|
||||
@@ -96,31 +96,46 @@ function UTIL:GetVehicleInDirection( entFrom, coordFrom, coordTo )
|
||||
return vehicle
|
||||
end
|
||||
|
||||
-- Returns if a target vehicle is coming towards or going away from the patrol vehicle, it has a range
|
||||
-- so if a vehicle is sideways compared to the patrol vehicle, the directional arrows won't light up
|
||||
-- Returns if a target vehicle is coming towards or going away from the patrol vehicle, it has a range
|
||||
-- so if a vehicle is sideways compared to the patrol vehicle, the directional arrows won't light up
|
||||
function UTIL:GetEntityRelativeDirection( myAng, tarAng )
|
||||
local angleDiff = math.abs( ( myAng - tarAng + 180 ) % 360 - 180 )
|
||||
|
||||
if ( angleDiff < 45 ) then
|
||||
if ( angleDiff < 45 ) then
|
||||
return 1
|
||||
elseif ( angleDiff > 135 ) then
|
||||
elseif ( angleDiff > 135 ) then
|
||||
return 2
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Your everyday GTA notification function
|
||||
-- Returns if there is a player in the given vehicle
|
||||
function UTIL:IsPlayerInVeh( veh )
|
||||
for i = -1, GetVehicleMaxNumberOfPassengers( veh ) + 1, 1 do
|
||||
local ped = GetPedInVehicleSeat( veh, i )
|
||||
|
||||
if ( DoesEntityExist( ped ) ) then
|
||||
if ( IsPedAPlayer( ped ) ) then return true end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Your everyday GTA notification function
|
||||
function UTIL:Notify( text )
|
||||
SetNotificationTextEntry( "STRING" )
|
||||
AddTextComponentSubstringPlayerName( text )
|
||||
DrawNotification( false, true )
|
||||
end
|
||||
|
||||
-- Prints the given message to the client console
|
||||
function UTIL:Log( msg )
|
||||
print( "[Wraith ARS 2X]: " .. msg )
|
||||
end
|
||||
end
|
||||
|
||||
-- Used to draw text to the screen, helpful for debugging issues
|
||||
function UTIL:DrawDebugText( x, y, scale, centre, text )
|
||||
SetTextFont( 4 )
|
||||
SetTextProportional( 0 )
|
||||
@@ -136,6 +151,11 @@ function UTIL:DrawDebugText( x, y, scale, centre, text )
|
||||
DrawText( x, y )
|
||||
end
|
||||
|
||||
-- Returns if the current resource name is valid
|
||||
function UTIL:IsResourceNameValid()
|
||||
return GetCurrentResourceName() == "wk_wars2x"
|
||||
end
|
||||
|
||||
--[[The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 IllidanS4
|
||||
|
||||
90
config.lua
90
config.lua
@@ -2,13 +2,13 @@
|
||||
|
||||
Wraith ARS 2X
|
||||
Created by WolfKnight
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -34,23 +34,39 @@
|
||||
CONFIG = {}
|
||||
|
||||
-- Radar fast limit locking
|
||||
-- When enabled, the player will be able to define a fast limit within the radar's menu, when a vehicle
|
||||
-- When enabled, the player will be able to define a fast limit within the radar's menu, when a vehicle
|
||||
-- exceeds the fast limit, it will be locked into the fast box. Default setting is disabled to maintain realism
|
||||
CONFIG.allow_fast_limit = false
|
||||
CONFIG.allow_fast_limit = true
|
||||
|
||||
-- Radar only lock players with auto fast locking
|
||||
-- When enabled, the radar will only automatically lock a speed if the caught vehicle has a real player in it.
|
||||
CONFIG.only_lock_players = false
|
||||
|
||||
-- In-game first time quick start video
|
||||
-- When enabled, the player will be asked if they'd like to view the quick start video the first time they
|
||||
-- open the remote.
|
||||
CONFIG.allow_quick_start_video = true
|
||||
-- When enabled, the player will be asked if they'd like to view the quick start video the first time they
|
||||
-- open the remote.
|
||||
CONFIG.allow_quick_start_video = true
|
||||
|
||||
-- Allow passenger view
|
||||
-- When enabled, the front seat passenger will be able to view the radar and plate reader from their end.
|
||||
CONFIG.allow_passenger_view = false
|
||||
|
||||
-- Allow passenger control
|
||||
-- Dependent on CONFIG.allow_passenger_view. When enabled, the front seat passenger will be able to open the
|
||||
-- radar remote and control the radar and plate reader for themself and the driver.
|
||||
CONFIG.allow_passenger_control = false
|
||||
|
||||
-- Set this to true if you use Sonoran CAD with the WraithV2 plugin
|
||||
CONFIG.use_sonorancad = false
|
||||
|
||||
-- Sets the defaults of all keybinds
|
||||
-- These keybinds can be changed by each person in their GTA Settings->Keybinds->FiveM
|
||||
CONFIG.keyDefaults =
|
||||
{
|
||||
-- Remote control key
|
||||
-- Remote control key
|
||||
remote_control = "f5",
|
||||
|
||||
-- Radar key lock key
|
||||
-- Radar key lock key
|
||||
key_lock = "l",
|
||||
|
||||
-- Radar front antenna lock/unlock Key
|
||||
@@ -67,33 +83,41 @@ CONFIG.keyDefaults =
|
||||
}
|
||||
|
||||
-- Here you can change the default values for the operator menu, do note, if any of these values are not
|
||||
-- one of the options listed, the script will not work.
|
||||
CONFIG.menuDefaults =
|
||||
-- one of the options listed, the script will not work.
|
||||
CONFIG.menuDefaults =
|
||||
{
|
||||
-- Should the system calculate and display faster targets
|
||||
-- Options: true or false
|
||||
["fastDisplay"] = true,
|
||||
["fastDisplay"] = true,
|
||||
|
||||
-- Sensitivity for each radar mode, this changes how far the antennas will detect vehicles
|
||||
-- Options: 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["same"] = 0.6,
|
||||
["opp"] = 0.6,
|
||||
["same"] = 0.6,
|
||||
["opp"] = 0.6,
|
||||
|
||||
-- The volume of the audible beep
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
-- The volume of the audible beep
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["beep"] = 0.6,
|
||||
|
||||
-- The volume of the verbal lock confirmation
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
|
||||
-- The volume of the verbal lock confirmation
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["voice"] = 0.6,
|
||||
|
||||
-- The volume of the plate reader audio
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["plateAudio"] = 0.6,
|
||||
|
||||
-- The volume of the plate reader audio
|
||||
-- Options: 0.0, 0.2, 0.4, 0.6, 0.8, 1.0
|
||||
["plateAudio"] = 0.6,
|
||||
|
||||
-- The speed unit used in conversions
|
||||
-- Options: mph or kmh
|
||||
["speedType"] = "mph"
|
||||
-- Options: mph or kmh
|
||||
["speedType"] = "mph",
|
||||
|
||||
-- The state for automatic speed locking. This requires CONFIG.allow_fast_limit to be true.
|
||||
-- Options: true or false
|
||||
["fastLock"] = false,
|
||||
|
||||
-- The speed limit required for automatic speed locking. This requires CONFIG.allow_fast_limit to be true.
|
||||
-- Options: 0 to 200
|
||||
["fastLimit"] = 60
|
||||
}
|
||||
|
||||
-- Here you can change the default scale of the UI elements, as well as the safezone size
|
||||
@@ -103,12 +127,12 @@ CONFIG.uiDefaults =
|
||||
-- Options: 0.25 - 2.5
|
||||
scale =
|
||||
{
|
||||
radar = 1.0,
|
||||
remote = 1.0,
|
||||
plateReader = 1.0
|
||||
},
|
||||
radar = 0.75,
|
||||
remote = 0.75,
|
||||
plateReader = 0.75
|
||||
},
|
||||
|
||||
-- The safezone size, must be a multiple of 5.
|
||||
-- Options: 0 - 100
|
||||
safezone = 20
|
||||
safezone = 20
|
||||
}
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
Wraith ARS 2X
|
||||
Created by WolfKnight
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -31,20 +31,19 @@
|
||||
---------------------------------------------------------------------------------------]]--
|
||||
|
||||
-- Define the FX Server version and game type
|
||||
fx_version "bodacious"
|
||||
fx_version "cerulean"
|
||||
game "gta5"
|
||||
|
||||
-- Define the resource metadata
|
||||
name "Wraith ARS 2X"
|
||||
description "Police radar and plate reader system for FiveM"
|
||||
author "WolfKnight"
|
||||
version "1.2.4"
|
||||
version "1.3.0"
|
||||
|
||||
-- Include the files
|
||||
files {
|
||||
"nui/radar.html",
|
||||
"nui/radar.css",
|
||||
"nui/jquery-3.4.1.min.js",
|
||||
"nui/radar.html",
|
||||
"nui/radar.css",
|
||||
"nui/radar.js",
|
||||
"nui/images/*.png",
|
||||
"nui/images/plates/*.png",
|
||||
@@ -59,10 +58,13 @@ ui_page "nui/radar.html"
|
||||
-- Run the server scripts
|
||||
server_script "sv_version_check.lua"
|
||||
server_script "sv_exports.lua"
|
||||
server_script "sv_sync.lua"
|
||||
server_export "TogglePlateLock"
|
||||
|
||||
-- Run the client scripts
|
||||
client_script "config.lua"
|
||||
client_script "cl_utils.lua"
|
||||
client_script "cl_player.lua"
|
||||
client_script "cl_radar.lua"
|
||||
client_script "cl_plate_reader.lua"
|
||||
client_script "cl_plate_reader.lua"
|
||||
client_script "cl_sync.lua"
|
||||
2
nui/jquery-3.4.1.min.js
vendored
2
nui/jquery-3.4.1.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -8,7 +8,7 @@
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -159,6 +159,14 @@ button:focus { outline: none; }
|
||||
color: rgb(255, 255, 0);
|
||||
}
|
||||
|
||||
.green {
|
||||
color: rgb( 0, 255, 0 );
|
||||
}
|
||||
|
||||
.red {
|
||||
color: rgb( 255, 0, 0 );
|
||||
}
|
||||
|
||||
.arrow {
|
||||
width: 11px;
|
||||
height: 15.4px;
|
||||
@@ -770,7 +778,7 @@ button:focus { outline: none; }
|
||||
|
||||
#plateReaderBox {
|
||||
width: 225px;
|
||||
height: 300px;
|
||||
height: 330px;
|
||||
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -245,6 +245,8 @@
|
||||
<input id="boloText" type="text" maxlength="8" placeholder="12ABC345" onkeypress="checkPlateInput(event)" class="plate_input"/>
|
||||
|
||||
<button id="setBoloPlate" class="btn">Set BOLO Plate</button>
|
||||
|
||||
<button id="clearBoloPlate" class="btn">Clear BOLO Plate</button>
|
||||
</div>
|
||||
|
||||
<button id="closePlateReaderSettings" class="close">CLOSE</button>
|
||||
@@ -298,7 +300,7 @@
|
||||
<button id="closeUiSettings" class="close">CLOSE</button>
|
||||
</div>
|
||||
|
||||
<p id="keyLockLabel">Radar key lock <span id="keyLockStateLabel"></span></p>
|
||||
<p id="keyLockLabel">Radar key binds <span id="keyLockStateLabel"></span></p>
|
||||
|
||||
<div id="helpWindow">
|
||||
<iframe id="helpWeb" src="about:blank"></iframe>
|
||||
@@ -317,7 +319,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Load JavaScript files -->
|
||||
<script src="jquery-3.4.1.min.js"></script>
|
||||
<script src="nui://game/ui/jquery.js" type="text/javascript"></script>
|
||||
<script src="radar.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
40
nui/radar.js
40
nui/radar.js
@@ -8,7 +8,7 @@
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -33,7 +33,6 @@
|
||||
/*------------------------------------------------------------------------------------
|
||||
Variables
|
||||
------------------------------------------------------------------------------------*/
|
||||
var resourceName;
|
||||
var uiEdited = false;
|
||||
|
||||
// All of the audio file names
|
||||
@@ -90,6 +89,7 @@ const elements =
|
||||
plateReaderBox: $( "#plateReaderBox" ),
|
||||
boloText: $( "#boloText" ),
|
||||
setBoloBtn: $( "#setBoloPlate" ),
|
||||
clearBoloBtn: $( "#clearBoloPlate" ),
|
||||
closePrBtn: $( "#closePlateReaderSettings" ),
|
||||
|
||||
openHelp: $( "#helpBtn" ),
|
||||
@@ -494,7 +494,7 @@ function poweringUp()
|
||||
}
|
||||
|
||||
// Simulates the 'fully powered' state of the radar unit
|
||||
function poweredUp()
|
||||
function poweredUp( fastDisplay )
|
||||
{
|
||||
// Completely clear everything
|
||||
clearEverything();
|
||||
@@ -505,14 +505,14 @@ function poweredUp()
|
||||
// Even though the clearEverything() function is called above, we run this so the fast window
|
||||
// displays 'HLd'
|
||||
setAntennaXmit( ant, false );
|
||||
setAntennaFastMode( ant, true );
|
||||
setAntennaFastMode( ant, fastDisplay );
|
||||
}
|
||||
}
|
||||
|
||||
// Runs the startup process or clears everything, the Lua side calls for the full powered up state
|
||||
function radarPower( state )
|
||||
function radarPower( state, override, fastDisplay )
|
||||
{
|
||||
state ? poweringUp() : clearEverything();
|
||||
state ? ( override ? poweredUp( fastDisplay ) : poweringUp() ) : clearEverything();
|
||||
}
|
||||
|
||||
|
||||
@@ -605,17 +605,27 @@ function menu( optionText, option )
|
||||
elements.patrolSpeed.html( option );
|
||||
}
|
||||
|
||||
var keyLockTimeout;
|
||||
|
||||
// Makes the key lock label fade in then fade out after 2 seconds
|
||||
function displayKeyLock( state )
|
||||
{
|
||||
let sl = elements.keyLock.stateLabel;
|
||||
|
||||
// Set the state label text to enabled or disabled
|
||||
elements.keyLock.stateLabel.html( state ? "enabled" : "disabled" );
|
||||
sl.html( state ? "blocked" : "enabled" );
|
||||
|
||||
// Change the colour of the altered text
|
||||
state ? sl.addClass( "red" ).removeClass( "green" ) : sl.addClass( "green" ).removeClass( "red" );
|
||||
|
||||
// Fade in the label
|
||||
elements.keyLock.label.fadeIn();
|
||||
|
||||
// Clear the timeout if it already exists
|
||||
clearTimeout( keyLockTimeout );
|
||||
|
||||
// Make the label fade out after 2 seconds
|
||||
setTimeout( function() {
|
||||
keyLockTimeout = setTimeout( function() {
|
||||
elements.keyLock.label.fadeOut();
|
||||
}, 2000 );
|
||||
}
|
||||
@@ -629,7 +639,7 @@ $.ajaxSetup({
|
||||
|
||||
// This function is used to send data back through to the LUA side
|
||||
function sendData( name, data ) {
|
||||
$.post( "https://" + resourceName + "/" + name, JSON.stringify( data ), function( datab ) {
|
||||
$.post( "https://wk_wars2x/" + name, JSON.stringify( data ), function( datab ) {
|
||||
if ( datab != "ok" ) {
|
||||
console.log( datab );
|
||||
}
|
||||
@@ -767,6 +777,11 @@ elements.setBoloBtn.click( function() {
|
||||
}
|
||||
} )
|
||||
|
||||
// Sets the on click function for the clear BOLO button
|
||||
elements.clearBoloBtn.click( function() {
|
||||
sendData( "clearBoloPlate", null );
|
||||
} )
|
||||
|
||||
// Checks what the user is typing into the plate box
|
||||
function checkPlateInput( event )
|
||||
{
|
||||
@@ -1077,9 +1092,6 @@ window.addEventListener( "message", function( event ) {
|
||||
|
||||
switch ( type ) {
|
||||
// System events
|
||||
case "updatePathName":
|
||||
resourceName = item.pathName
|
||||
break;
|
||||
case "loadUiSettings":
|
||||
loadUiSettings( item.data, true );
|
||||
break;
|
||||
@@ -1102,10 +1114,10 @@ window.addEventListener( "message", function( event ) {
|
||||
setEleVisible( elements.radar, item.state );
|
||||
break;
|
||||
case "radarPower":
|
||||
radarPower( item.state );
|
||||
radarPower( item.state, item.override, item.fast );
|
||||
break;
|
||||
case "poweredUp":
|
||||
poweredUp();
|
||||
poweredUp( item.fast );
|
||||
break;
|
||||
case "update":
|
||||
updateDisplays( item.speed, item.antennas );
|
||||
|
||||
78
sv_sync.lua
Normal file
78
sv_sync.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
--[[---------------------------------------------------------------------------------------
|
||||
|
||||
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-2021 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.
|
||||
|
||||
---------------------------------------------------------------------------------------]]--
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Sync server events
|
||||
----------------------------------------------------------------------------------]]--
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendPowerState" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendPowerState", function( target, state )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receivePowerState", target, state )
|
||||
end )
|
||||
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendAntennaPowerState" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendAntennaPowerState", function( target, state, ant )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receiveAntennaPowerState", target, state, ant )
|
||||
end )
|
||||
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendAntennaMode" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendAntennaMode", function( target, ant, mode )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receiveAntennaMode", target, ant, mode )
|
||||
end )
|
||||
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendLockAntennaSpeed" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendLockAntennaSpeed", function( target, ant, data )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receiveLockAntennaSpeed", target, ant, data )
|
||||
end )
|
||||
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendLockCameraPlate" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendLockCameraPlate", function( target, cam, data )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receiveLockCameraPlate", target, cam, data )
|
||||
end )
|
||||
|
||||
|
||||
--[[----------------------------------------------------------------------------------
|
||||
Radar data sync server events
|
||||
----------------------------------------------------------------------------------]]--
|
||||
RegisterNetEvent( "wk_wars2x_sync:requestRadarData" )
|
||||
AddEventHandler( "wk_wars2x_sync:requestRadarData", function( target )
|
||||
TriggerClientEvent( "wk_wars2x_sync:getRadarDataFromDriver", target, source )
|
||||
end )
|
||||
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendRadarDataForPassenger" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendRadarDataForPassenger", function( playerFor, data )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receiveRadarData", playerFor, data )
|
||||
end )
|
||||
|
||||
RegisterNetEvent( "wk_wars2x_sync:sendUpdatedOMData" )
|
||||
AddEventHandler( "wk_wars2x_sync:sendUpdatedOMData", function( playerFor, data )
|
||||
TriggerClientEvent( "wk_wars2x_sync:receiveUpdatedOMData", playerFor, data )
|
||||
end )
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
Wraith ARS 2X
|
||||
Created by WolfKnight
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
|
||||
For discussions, information on future updates, and more, join
|
||||
my Discord: https://discord.gg/fD4e6WD
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 WolfKnight
|
||||
Copyright (c) 2020-2021 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
|
||||
@@ -31,48 +31,52 @@
|
||||
---------------------------------------------------------------------------------------]]--
|
||||
|
||||
-- Branding!
|
||||
local label =
|
||||
local label =
|
||||
[[
|
||||
//
|
||||
|| __ __ _ _ _ _____ _____ ___ __ __
|
||||
|| \ \ / / (_) | | | /\ | __ \ / ____| |__ \\ \ / /
|
||||
|| \ \ /\ / / __ __ _ _| |_| |__ / \ | |__) | (___ ) |\ V /
|
||||
|| \ \/ \/ / '__/ _` | | __| '_ \ / /\ \ | _ / \___ \ / / > <
|
||||
|| \ /\ /| | | (_| | | |_| | | | / ____ \| | \ \ ____) | / /_ / . \
|
||||
|| \/ \/ |_| \__,_|_|\__|_| |_| /_/ \_\_| \_\_____/ |____/_/ \_\
|
||||
||
|
||||
|| Created by WolfKnight
|
||||
|| __ __ _ _ _ _ ___ ___ _____ __
|
||||
|| \ \ / / _ __ _(_) |_| |_ /_\ | _ \/ __| |_ ) \/ /
|
||||
|| \ \/\/ / '_/ _` | | _| ' \ / _ \| /\__ \ / / > <
|
||||
|| \_/\_/|_| \__,_|_|\__|_||_| /_/ \_\_|_\|___/ /___/_/\_\
|
||||
||
|
||||
|| Created by WolfKnight
|
||||
||]]
|
||||
|
||||
-- Returns the current version set in fxmanifest.lua
|
||||
function GetCurrentVersion()
|
||||
return GetResourceMetadata( GetCurrentResourceName(), "version" )
|
||||
end
|
||||
end
|
||||
|
||||
-- Grabs the latest version number from the web GitHub
|
||||
PerformHttpRequest( "https://wolfknight98.github.io/wk_wars2x_web/version.txt", function( err, text, headers )
|
||||
-- Wait to reduce spam
|
||||
-- Wait to reduce spam
|
||||
Citizen.Wait( 2000 )
|
||||
|
||||
-- Print the branding!
|
||||
print( label )
|
||||
|
||||
-- Get the current resource version
|
||||
-- Get the current resource version
|
||||
local curVer = GetCurrentVersion()
|
||||
|
||||
if ( text ~= nil ) then
|
||||
-- Print out the current and latest version
|
||||
print( " || Current version: " .. curVer )
|
||||
|
||||
print( " || Current version: " .. curVer )
|
||||
|
||||
if ( text ~= nil ) then
|
||||
-- Print latest version
|
||||
print( " || Latest recommended version: " .. text .."\n ||" )
|
||||
|
||||
|
||||
-- If the versions are different, print it out
|
||||
if ( text ~= curVer ) then
|
||||
print( " || ^1Your Wraith ARS 2X version is outdated, visit the FiveM forum post to get the latest version.\n^0 \\\\\n" )
|
||||
else
|
||||
print( " || ^2Wraith ARS 2X is up to date!\n^0 ||\n \\\\\n" )
|
||||
end
|
||||
else
|
||||
else
|
||||
-- In case the version can not be requested, print out an error message
|
||||
print( " || ^1There was an error getting the latest version information, if the issue persists contact WolfKnight#8586 on Discord.\n^0 ||\n \\\\\n" )
|
||||
end
|
||||
print( " || ^1There was an error getting the latest version information.\n^0 ||\n \\\\\n" )
|
||||
end
|
||||
|
||||
-- Warn the console if the resource has been renamed, as this will cause issues with the resource's functionality.
|
||||
if ( GetCurrentResourceName() ~= "wk_wars2x" ) then
|
||||
print( "^1ERROR: Resource name is not wk_wars2x, expect there to be issues with the resource. To ensure there are no issues, please leave the resource name as wk_wars2x^0\n\n" )
|
||||
end
|
||||
end )
|
||||
Reference in New Issue
Block a user