mirror of
https://github.com/Michatec/wk_wars2x.git
synced 2026-04-01 08:26:27 +02:00
UI settings now get saved and loaded
This commit is contained in:
@@ -10,7 +10,7 @@ resource_manifest_version '44febabe-d386-4d18-afbe-5e627f4af937'
|
|||||||
name 'Wraith ARS 2X'
|
name 'Wraith ARS 2X'
|
||||||
description 'An advanced radar system for FiveM'
|
description 'An advanced radar system for FiveM'
|
||||||
author 'WolfKnight'
|
author 'WolfKnight'
|
||||||
version 'beta3'
|
version 'beta3b'
|
||||||
|
|
||||||
files {
|
files {
|
||||||
"nui/radar.html",
|
"nui/radar.html",
|
||||||
@@ -25,6 +25,7 @@ files {
|
|||||||
ui_page "nui/radar.html"
|
ui_page "nui/radar.html"
|
||||||
|
|
||||||
server_script 'sv_version_check.lua'
|
server_script 'sv_version_check.lua'
|
||||||
|
server_script 'sv_saving.lua'
|
||||||
|
|
||||||
client_script 'config.lua'
|
client_script 'config.lua'
|
||||||
client_script 'cl_utils.lua'
|
client_script 'cl_utils.lua'
|
||||||
|
|||||||
26
cl_radar.lua
26
cl_radar.lua
@@ -30,6 +30,23 @@ Citizen.SetTimeout( 1000, function()
|
|||||||
end )
|
end )
|
||||||
|
|
||||||
|
|
||||||
|
--[[----------------------------------------------------------------------------------
|
||||||
|
UI loading trigger
|
||||||
|
----------------------------------------------------------------------------------]]--
|
||||||
|
local spawned = false
|
||||||
|
|
||||||
|
AddEventHandler( "playerSpawned", function()
|
||||||
|
if ( not spawned ) then
|
||||||
|
TriggerServerEvent( "wk:getUiData" )
|
||||||
|
spawned = true
|
||||||
|
end
|
||||||
|
end )
|
||||||
|
|
||||||
|
RegisterNetEvent( "wk:loadUiData" )
|
||||||
|
AddEventHandler( "wk:loadUiData", function( data )
|
||||||
|
SendNUIMessage( { _type = "loadUiSettings", data = data } )
|
||||||
|
end )
|
||||||
|
|
||||||
--[[----------------------------------------------------------------------------------
|
--[[----------------------------------------------------------------------------------
|
||||||
Player info variables
|
Player info variables
|
||||||
----------------------------------------------------------------------------------]]--
|
----------------------------------------------------------------------------------]]--
|
||||||
@@ -1325,6 +1342,11 @@ RegisterNUICallback( "menu", function()
|
|||||||
SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } )
|
SendNUIMessage( { _type = "audio", name = "beep", vol = RADAR:GetSettingValue( "beep" ) } )
|
||||||
end )
|
end )
|
||||||
|
|
||||||
|
-- Runs when the JavaScript side sends the UI data for saving
|
||||||
|
RegisterNUICallback( "saveUiData", function( data, cb )
|
||||||
|
TriggerServerEvent( "wk:saveUiData", data )
|
||||||
|
end )
|
||||||
|
|
||||||
|
|
||||||
--[[----------------------------------------------------------------------------------
|
--[[----------------------------------------------------------------------------------
|
||||||
Main threads
|
Main threads
|
||||||
@@ -1587,9 +1609,9 @@ function RADAR: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
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ button:focus { outline: none; }
|
|||||||
|
|
||||||
/* Settings for scaling */
|
/* Settings for scaling */
|
||||||
transform: scale( 1.0 );
|
transform: scale( 1.0 );
|
||||||
transform-origin: 0 0;
|
transform-origin: 0 0;
|
||||||
|
|
||||||
|
transition: transform 0.5s;
|
||||||
|
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
@@ -365,7 +367,9 @@ button:focus { outline: none; }
|
|||||||
|
|
||||||
color: white;
|
color: white;
|
||||||
/* background-color: rgb( 50, 50, 50 ); */
|
/* background-color: rgb( 50, 50, 50 ); */
|
||||||
background-image: url( "images/rc_bg.png" );
|
background-image: url( "images/rc_bg.png" );
|
||||||
|
|
||||||
|
transition: transform 0.5s;
|
||||||
|
|
||||||
/* clip-path: polygon( 5% 0, 95% 0, 100% 25%, 90% 100%, 10% 100%, 0 25% ); */
|
/* clip-path: polygon( 5% 0, 95% 0, 100% 25%, 90% 100%, 10% 100%, 0 25% ); */
|
||||||
|
|
||||||
|
|||||||
101
nui/radar.js
101
nui/radar.js
@@ -12,6 +12,7 @@
|
|||||||
Variables
|
Variables
|
||||||
------------------------------------------------------------------------------------*/
|
------------------------------------------------------------------------------------*/
|
||||||
var resourceName;
|
var resourceName;
|
||||||
|
var uiEdited = false;
|
||||||
|
|
||||||
const audioNames =
|
const audioNames =
|
||||||
{
|
{
|
||||||
@@ -399,16 +400,77 @@ function sendData( name, data ) {
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setUiHasBeenEdited( state )
|
||||||
|
{
|
||||||
|
uiEdited = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasUiBeenEdited()
|
||||||
|
{
|
||||||
|
return uiEdited;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendSaveData()
|
||||||
|
{
|
||||||
|
if ( hasUiBeenEdited() ) {
|
||||||
|
let data =
|
||||||
|
{
|
||||||
|
remote: {
|
||||||
|
left: elements.remote.css( "left" ),
|
||||||
|
top: elements.remote.css( "top" ),
|
||||||
|
scale: remoteScale
|
||||||
|
},
|
||||||
|
|
||||||
|
radar: {
|
||||||
|
left: elements.radar.css( "left" ),
|
||||||
|
top: elements.radar.css( "top" ),
|
||||||
|
scale: radarScale
|
||||||
|
},
|
||||||
|
|
||||||
|
safezone: safezone
|
||||||
|
}
|
||||||
|
|
||||||
|
sendData( "saveUiData", data );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadUiSettings( data )
|
||||||
|
{
|
||||||
|
// Iterate through "remote" and "radar"
|
||||||
|
for ( let setting of [ "remote", "radar" ] )
|
||||||
|
{
|
||||||
|
// Iterate through the settings
|
||||||
|
for ( let i of [ "left", "top" ] )
|
||||||
|
{
|
||||||
|
// Update the position of the current element
|
||||||
|
elements[setting].css( i, data[setting][i] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the scale and update the display
|
||||||
|
setScaleAndDisplay( elements[setting], data[setting].scale, elements[setting + "Scaling"].display );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the remote and radar scale variables
|
||||||
|
remoteScale = data.remote.scale;
|
||||||
|
radarScale = data.radar.scale;
|
||||||
|
|
||||||
|
// Set the safezone and update the display
|
||||||
|
elements.safezoneSlider.val( data.safezone );
|
||||||
|
elements.safezoneSlider.trigger( "input" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------------
|
||||||
UI scaling and positioning
|
UI scaling and positioning
|
||||||
------------------------------------------------------------------------------------*/
|
------------------------------------------------------------------------------------*/
|
||||||
var remoteScale = 1.0;
|
var remoteScale = 1.0;
|
||||||
var remoteMoving = false;
|
var remoteMoving = false;
|
||||||
|
var remoteLastOffset = [ 0, 0 ];
|
||||||
var remoteOffset = [ 0, 0 ];
|
var remoteOffset = [ 0, 0 ];
|
||||||
|
|
||||||
var radarScale = 1.0;
|
var radarScale = 1.0;
|
||||||
var radarMoving = false;
|
var radarMoving = false;
|
||||||
|
var radarLastOffset = [ 0, 0 ];
|
||||||
var radarOffset = [ 0, 0 ];
|
var radarOffset = [ 0, 0 ];
|
||||||
|
|
||||||
var windowWidth = 0;
|
var windowWidth = 0;
|
||||||
@@ -457,6 +519,7 @@ elements.radar.mousedown( function( event ) {
|
|||||||
} )
|
} )
|
||||||
|
|
||||||
$( document ).mouseup( function( event ) {
|
$( document ).mouseup( function( event ) {
|
||||||
|
// Reset the remote and radar moving variables
|
||||||
remoteMoving = false;
|
remoteMoving = false;
|
||||||
radarMoving = false;
|
radarMoving = false;
|
||||||
} )
|
} )
|
||||||
@@ -503,6 +566,8 @@ function calculatePos( ele, x, y, w, h, offset, scale, safezone )
|
|||||||
let eleHeight = ( ele.outerHeight() * scale );
|
let eleHeight = ( ele.outerHeight() * scale );
|
||||||
let eleWidthPerct = ( eleWidth / w ) * 100;
|
let eleWidthPerct = ( eleWidth / w ) * 100;
|
||||||
let eleHeightPerct = ( eleHeight / h ) * 100;
|
let eleHeightPerct = ( eleHeight / h ) * 100;
|
||||||
|
let eleWidthPerctHalf = eleWidthPerct / 2;
|
||||||
|
let eleHeightPerctHalf = eleHeightPerct / 2;
|
||||||
|
|
||||||
let maxWidth = w - eleWidth;
|
let maxWidth = w - eleWidth;
|
||||||
let maxHeight = h - eleHeight;
|
let maxHeight = h - eleHeight;
|
||||||
@@ -513,18 +578,22 @@ function calculatePos( ele, x, y, w, h, offset, scale, safezone )
|
|||||||
let leftPos = ( left / w ) * 100;
|
let leftPos = ( left / w ) * 100;
|
||||||
let topPos = ( top / h ) * 100;
|
let topPos = ( top / h ) * 100;
|
||||||
|
|
||||||
|
let leftLockGap = leftPos + eleWidthPerctHalf;
|
||||||
|
let topLockGap = topPos + eleHeightPerctHalf;
|
||||||
|
|
||||||
// Lock pos check
|
// Lock pos check
|
||||||
if ( ( leftPos + ( eleWidthPerct / 2 ) ) >= 49.0 && ( leftPos + ( eleWidthPerct / 2 ) ) <= 51.0 )
|
if ( leftLockGap >= 48.0 && leftLockGap <= 52.0 )
|
||||||
{
|
{
|
||||||
leftPos = 50.0 - ( eleWidthPerct / 2 );
|
leftPos = 50.0 - eleWidthPerctHalf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( topPos + ( eleHeightPerct / 2 ) ) >= 49.0 && ( topPos + ( eleHeightPerct / 2 ) ) <= 51.0 )
|
if ( topLockGap >= 48.0 && topLockGap <= 52.0 )
|
||||||
{
|
{
|
||||||
topPos = 50.0 - ( eleHeightPerct / 2 );
|
topPos = 50.0 - eleHeightPerctHalf;
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePosition( ele, leftPos, topPos );
|
updatePosition( ele, leftPos, topPos );
|
||||||
|
setUiHasBeenEdited( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
function updatePosition( ele, left, top )
|
function updatePosition( ele, left, top )
|
||||||
@@ -556,9 +625,14 @@ function hideUISettings()
|
|||||||
|
|
||||||
function changeEleScale( ele, scaleVar, amount, display )
|
function changeEleScale( ele, scaleVar, amount, display )
|
||||||
{
|
{
|
||||||
|
// Change the scale of the element and update it's displayer
|
||||||
let scale = changeScale( ele, scaleVar, amount );
|
let scale = changeScale( ele, scaleVar, amount );
|
||||||
display.html( scale.toFixed( 2 ) + "x" );
|
display.html( scale.toFixed( 2 ) + "x" );
|
||||||
|
|
||||||
|
// Tell the system the UI has been edited
|
||||||
|
// !uiEdited ? uiEdited = true : null;
|
||||||
|
setUiHasBeenEdited( true );
|
||||||
|
|
||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,6 +644,12 @@ function changeScale( ele, current, amount )
|
|||||||
return scale;
|
return scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setScaleAndDisplay( ele, scale, display )
|
||||||
|
{
|
||||||
|
ele.css( "transform", "scale(" + scale + ")" );
|
||||||
|
display.html( scale.toFixed( 2 ) + "x" );
|
||||||
|
}
|
||||||
|
|
||||||
function clamp( num, min, max )
|
function clamp( num, min, max )
|
||||||
{
|
{
|
||||||
return num < min ? min : num > max ? max : num;
|
return num < min ? min : num > max ? max : num;
|
||||||
@@ -600,7 +680,9 @@ function closeRemote()
|
|||||||
{
|
{
|
||||||
sendData( "closeRemote", null );
|
sendData( "closeRemote", null );
|
||||||
setRemoteVisible( false );
|
setRemoteVisible( false );
|
||||||
setUISettingsVisible( false, false );
|
setUISettingsVisible( false, false );
|
||||||
|
|
||||||
|
sendSaveData();
|
||||||
}
|
}
|
||||||
|
|
||||||
$( document ).keyup( function( event ) {
|
$( document ).keyup( function( event ) {
|
||||||
@@ -626,9 +708,14 @@ window.addEventListener( "message", function( event ) {
|
|||||||
switch ( type ) {
|
switch ( type ) {
|
||||||
case "updatePathName":
|
case "updatePathName":
|
||||||
resourceName = item.pathName
|
resourceName = item.pathName
|
||||||
break;
|
break;
|
||||||
|
case "loadUiSettings":
|
||||||
|
loadUiSettings( item.data );
|
||||||
|
break;
|
||||||
case "openRemote":
|
case "openRemote":
|
||||||
setRemoteVisible( true );
|
setRemoteVisible( true );
|
||||||
|
// uiEdited = false;
|
||||||
|
setUiHasBeenEdited( false );
|
||||||
break;
|
break;
|
||||||
case "toggleDisplay":
|
case "toggleDisplay":
|
||||||
setRadarVisible( item.state );
|
setRadarVisible( item.state );
|
||||||
|
|||||||
130
sv_saving.lua
Normal file
130
sv_saving.lua
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
--[[-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Wraith ARS 2X
|
||||||
|
Created by WolfKnight
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------]]--
|
||||||
|
|
||||||
|
local DATASAVE = {}
|
||||||
|
DATASAVE.dir = "saves"
|
||||||
|
|
||||||
|
-- Change this to whatever ID type you want to use for saving user data
|
||||||
|
-- Options are:
|
||||||
|
-- - steam
|
||||||
|
-- - license
|
||||||
|
-- - xbl
|
||||||
|
-- - live
|
||||||
|
-- - discord
|
||||||
|
-- - fivem
|
||||||
|
-- - ip
|
||||||
|
DATASAVE.idType = "license"
|
||||||
|
|
||||||
|
-- Saves the data for the given player into the saves folder within the resource
|
||||||
|
function DATASAVE:SavePlayerData( src, data )
|
||||||
|
-- Get the player's identifier
|
||||||
|
local id = self:GetIdentifier( src )
|
||||||
|
|
||||||
|
-- Save the JSON file into the saves folder
|
||||||
|
SaveResourceFile( GetCurrentResourceName(), self.dir .. "/" .. id .. ".json", json.encode( data ), -1 )
|
||||||
|
|
||||||
|
-- Print out a message in the console to say the player's UI data has been saved
|
||||||
|
self:Print( "Saved UI data for " .. GetPlayerName( src ) .. " (ID: " .. src .. ")" )
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Attempts to retrieve the UI data for the given player
|
||||||
|
function DATASAVE:GetPlayerData( src )
|
||||||
|
-- Get the player's identifier
|
||||||
|
local id = self:GetIdentifier( src )
|
||||||
|
|
||||||
|
-- Try to grab the raw data from the player's JSON file
|
||||||
|
local rawData = LoadResourceFile( GetCurrentResourceName(), self.dir .. "/" .. id .. ".json" )
|
||||||
|
|
||||||
|
-- In the event there is no file for the player, return nil
|
||||||
|
if ( rawData == nil ) then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Decode the JSON data into a Lua table
|
||||||
|
local data = json.decode( rawData )
|
||||||
|
|
||||||
|
-- Return the data
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
function DATASAVE:CheckDataIsValid( data )
|
||||||
|
-- First we check to make sure the data being passed is actually a table
|
||||||
|
if ( type( data ) ~= "table" ) then return false end
|
||||||
|
|
||||||
|
-- Then we check to make sure that the data has only 3 elements, "remote", "radar" and "safezone"
|
||||||
|
local c = 0
|
||||||
|
for _ in pairs( data ) do c = c + 1 end
|
||||||
|
|
||||||
|
-- If there isn't 3 elements, then the data isn't valid
|
||||||
|
if ( c ~= 3 ) then return false end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function DATASAVE:GetIdentifier( src )
|
||||||
|
local max = GetNumPlayerIdentifiers( src )
|
||||||
|
|
||||||
|
for i = 0, max do
|
||||||
|
local id = GetPlayerIdentifier( src, i )
|
||||||
|
|
||||||
|
if ( id == nil ) then
|
||||||
|
self:Print( "^1It appears there was an error trying to find the specified ID (" .. self.idType .. ") for player " .. GetPlayerName( source ) )
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if ( string.find( id, self.idType, 1 ) ) then
|
||||||
|
local split = self:SplitString( id, ":" )
|
||||||
|
return split[2]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function DATASAVE:SplitString( inputstr, sep )
|
||||||
|
if ( sep == nil ) then
|
||||||
|
sep = "%s"
|
||||||
|
end
|
||||||
|
|
||||||
|
local t = {}
|
||||||
|
local i = 1
|
||||||
|
|
||||||
|
for str in string.gmatch( inputstr, "([^" .. sep .. "]+)" ) do
|
||||||
|
t[i] = str
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return t
|
||||||
|
end
|
||||||
|
|
||||||
|
function DATASAVE:Print( msg )
|
||||||
|
print( "^3[wk_wars2x] ^0" .. msg .. "^0" )
|
||||||
|
end
|
||||||
|
|
||||||
|
RegisterServerEvent( "wk:saveUiData" )
|
||||||
|
AddEventHandler( "wk:saveUiData", function( data )
|
||||||
|
-- Check to make sure that the data being sent by the client is valid
|
||||||
|
local valid = DATASAVE:CheckDataIsValid( data )
|
||||||
|
|
||||||
|
-- Only proceed if the data is actually valid
|
||||||
|
if ( valid ) then
|
||||||
|
DATASAVE:SavePlayerData( source, data )
|
||||||
|
else
|
||||||
|
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 )
|
||||||
|
|
||||||
|
RegisterServerEvent( "wk:getUiData" )
|
||||||
|
AddEventHandler( "wk:getUiData", function()
|
||||||
|
local data = DATASAVE:GetPlayerData( source )
|
||||||
|
|
||||||
|
if ( data ) then
|
||||||
|
TriggerClientEvent( "wk:loadUiData", source, data )
|
||||||
|
else
|
||||||
|
DATASAVE:Print( "Player " .. GetPlayerName( source ) .. " (ID: " .. source .. ") doesn't have a UI settings file." )
|
||||||
|
end
|
||||||
|
end )
|
||||||
Reference in New Issue
Block a user