166 lines
5.2 KiB
Lua
166 lines
5.2 KiB
Lua
-- =============================================
|
|
-- This file contains any strictly *pure* functions
|
|
-- that are utilized by the rest of the menu.
|
|
-- Many of them need to be available with menu disabled
|
|
-- =============================================
|
|
|
|
--- Send a persistent alert to NUI
|
|
---@param key string An unique ID for this alert
|
|
---@param level string The level for the alert
|
|
---@param message string The message for this alert
|
|
---@param isTranslationKey boolean Whether the message is a translation key
|
|
function sendPersistentAlert(key, level, message, isTranslationKey)
|
|
debugPrint(('Sending persistent alert, key: %s, level: %s, message: %s'):format(key, level, message))
|
|
sendMenuMessage('setPersistentAlert', { key = key, level = level, message = message, isTranslationKey = isTranslationKey })
|
|
end
|
|
|
|
--- Clear a persistent alert on screen
|
|
---@param key string The unique ID passed in sendPersistentAlert for the notification
|
|
function clearPersistentAlert(key)
|
|
debugPrint(('Clearing persistent alert, key: %s'):format(key))
|
|
sendMenuMessage('clearPersistentAlert', { key = key })
|
|
end
|
|
|
|
--- Snackbar message
|
|
---@param level string The severity of the message can be 'info', 'error', or 'warning'
|
|
---@param message string Message to display with snackbar
|
|
---@param isTranslationKey boolean
|
|
---@param tOptions table | nil
|
|
function sendSnackbarMessage(level, message, isTranslationKey, tOptions)
|
|
debugPrint(('Sending snackbar message, level: %s, message: %s, isTranslationKey: %s'):format(level, message, isTranslationKey))
|
|
sendMenuMessage(
|
|
'setSnackbarAlert',
|
|
{
|
|
level = level,
|
|
message = message,
|
|
isTranslationKey = isTranslationKey,
|
|
tOptions = tOptions
|
|
}
|
|
)
|
|
end
|
|
|
|
--- Send data to the NUI frame
|
|
---@param action string Action
|
|
---@param data any Data corresponding to action
|
|
function sendMenuMessage(action, data)
|
|
SendNUIMessage({
|
|
action = action,
|
|
data = data
|
|
})
|
|
end
|
|
|
|
--- Close the menu if pause menu is opened using the default P key
|
|
local function createPauseMenuCheckerThread()
|
|
debugPrint('Starting pause menu checker thread')
|
|
CreateThread(function()
|
|
while isMenuVisible do
|
|
if IsPauseMenuActive() then
|
|
toggleMenuVisibility(false)
|
|
end
|
|
Wait(250)
|
|
end
|
|
end)
|
|
end
|
|
|
|
--- Toggle visibility of the txAdmin NUI menu
|
|
function toggleMenuVisibility(visible)
|
|
if (visible == true and isMenuVisible) or (visible == false and not isMenuVisible) then
|
|
return
|
|
end
|
|
if visible == nil then
|
|
if not isMenuVisible and IsPauseMenuActive() then
|
|
return
|
|
end
|
|
end
|
|
|
|
sendReactPlayerlist()
|
|
if visible ~= nil then
|
|
isMenuVisible = visible
|
|
sendMenuMessage('setVisible', visible)
|
|
else
|
|
isMenuVisible = not isMenuVisible
|
|
sendMenuMessage('setVisible', isMenuVisible)
|
|
end
|
|
createPauseMenuCheckerThread()
|
|
|
|
-- check if noclip and spectate still works with menu closed
|
|
if not isMenuVisible then
|
|
SetNuiFocus(false)
|
|
SetNuiFocusKeepInput(false)
|
|
tsLastMenuClose = GetGameTimer()
|
|
end
|
|
playLibrarySound('enter')
|
|
end
|
|
|
|
--- Calculate a safe Z coordinate based off the (X, Y)
|
|
---@param x number
|
|
---@param y number
|
|
---@return number|nil
|
|
function FindZForCoords(x, y)
|
|
local found = true
|
|
local START_Z = 1500
|
|
local z = START_Z
|
|
while found and z > 0 do
|
|
local _found, _z = GetGroundZAndNormalFor_3dCoord(x + 0.0, y + 0.0, z - 1.0)
|
|
if _found then
|
|
z = _z + 0.0
|
|
end
|
|
found = _found
|
|
Wait(0)
|
|
end
|
|
if z == START_Z then return nil end
|
|
return z + 0.0
|
|
end
|
|
|
|
--- Display simple help scaleform
|
|
---@param msg string - The message to display
|
|
function DisplayHelpTxtThisFrame(msg)
|
|
BeginTextCommandDisplayHelp('STRING')
|
|
AddTextComponentString(msg)
|
|
AddTextComponentSubstringTextLabel(msg)
|
|
EndTextCommandDisplayHelp(0, 1, 0, -1);
|
|
end
|
|
|
|
--- Used for local feedback and permission checks. Checks are still
|
|
--- performed on the server.
|
|
---@param perms table Array of all player permissions
|
|
---@param perm string The specific permission
|
|
---@return boolean
|
|
function DoesPlayerHavePerm(perms, perm)
|
|
if type(perms) ~= 'table' then
|
|
return false
|
|
end
|
|
|
|
for _, v in pairs(perms) do
|
|
if v == perm or v == 'all_permissions' then
|
|
return true
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
-- Sound libraries
|
|
local fivemSoundLibrary = {
|
|
move = {'NAV_UP_DOWN', 'HUD_FRONTEND_DEFAULT_SOUNDSET'},
|
|
enter = {'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET'},
|
|
confirm = {'CONFIRM_BEEP', 'HUD_MINI_GAME_SOUNDSET'},
|
|
}
|
|
local redmSoundLibrary = {
|
|
move = {'round_start_countdown_tick', 'RDRO_Poker_Sounds'},
|
|
enter = {'BET_PROMPT', 'HUD_POKER'},
|
|
confirm = {'BULLSEYE', 'FMA_ARCHERY_Sounds'},
|
|
}
|
|
|
|
--- Used to play UI sounds
|
|
---@param sound string
|
|
function playLibrarySound(sound)
|
|
if IS_FIVEM then
|
|
PlaySoundFrontend(-1, fivemSoundLibrary[sound][1], fivemSoundLibrary[sound][2], 1)
|
|
else
|
|
Citizen.InvokeNative(0x9D746964E0CF2C5F, redmSoundLibrary[sound][1], redmSoundLibrary[sound][2]) -- ReleaseShardSounds
|
|
Wait(0)
|
|
PlaySoundFrontend(redmSoundLibrary[sound][1], redmSoundLibrary[sound][2], true, 1);
|
|
end
|
|
end
|