mirror of
https://github.com/CommunityOx/ox_lib.git
synced 2026-08-16 22:46:03 +01:00
refactor(resource/interface): formatting and type definitions
This commit is contained in:
@@ -1,5 +1,13 @@
|
||||
local alert = nil
|
||||
|
||||
---@class AlertDialogProps
|
||||
---@field header string;
|
||||
---@field content string;
|
||||
---@field centered? boolean?;
|
||||
---@field cancel? boolean?;
|
||||
|
||||
---@param data AlertDialogProps
|
||||
---@return 'cancel' | 'confirm' | nil
|
||||
function lib.alertDialog(data)
|
||||
if alert then return end
|
||||
alert = promise.new()
|
||||
@@ -21,4 +29,4 @@ RegisterNUICallback('closeAlert', function(data, cb)
|
||||
promise:resolve(data)
|
||||
end)
|
||||
|
||||
RegisterNetEvent('ox_lib:alertDialog', lib.alertDialog)
|
||||
RegisterNetEvent('ox_lib:alertDialog', lib.alertDialog)
|
||||
@@ -1,6 +1,7 @@
|
||||
---@param value string
|
||||
function lib.setClipboard(value)
|
||||
SendNUIMessage({
|
||||
action = 'setClipboard',
|
||||
data = value
|
||||
})
|
||||
end
|
||||
SendNUIMessage({
|
||||
action = 'setClipboard',
|
||||
data = value
|
||||
})
|
||||
end
|
||||
@@ -1,16 +1,41 @@
|
||||
local contextMenus = {}
|
||||
local openContextMenu = nil
|
||||
|
||||
---@class ContextMenuItem
|
||||
---@field title? string
|
||||
---@field menu? string
|
||||
---@field icon? string
|
||||
---@field iconColor? string
|
||||
---@field onSelect? fun(args: any)
|
||||
---@field arrow? boolean
|
||||
---@field description? string
|
||||
---@field metadata? string | { [string]: any } | string[]
|
||||
---@field event? string
|
||||
---@field serverEvent? string
|
||||
---@field args? any
|
||||
|
||||
---@class ContextMenuArrayItem : ContextMenuItem
|
||||
---@field title string
|
||||
|
||||
---@class ContextMenuProps
|
||||
---@field id string
|
||||
---@field title string
|
||||
---@field menu? string
|
||||
---@field onExit? fun()
|
||||
---@field canClose? boolean
|
||||
---@field options { [string]: ContextMenuItem } | ContextMenuArrayItem[]
|
||||
|
||||
local function closeContext(_, cb, onExit)
|
||||
if cb then cb(1) end
|
||||
if (cb or onExit) and contextMenus[openContextMenu].onExit then contextMenus[openContextMenu].onExit() end
|
||||
SetNuiFocus(false, false)
|
||||
if not cb then SendNUIMessage({action = 'hideContext'}) end
|
||||
if not cb then SendNUIMessage({ action = 'hideContext' }) end
|
||||
openContextMenu = nil
|
||||
end
|
||||
|
||||
---@param id string
|
||||
function lib.showContext(id)
|
||||
if not contextMenus[id] then return error('No context menu of such id found.') end
|
||||
if not contextMenus[id] then error('No context menu of such id found.') end
|
||||
local data = contextMenus[id]
|
||||
openContextMenu = id
|
||||
SetNuiFocus(true, true)
|
||||
@@ -25,6 +50,7 @@ function lib.showContext(id)
|
||||
}, { sort_keys = true }))
|
||||
end
|
||||
|
||||
---@param context ContextMenuProps | ContextMenuProps[]
|
||||
function lib.registerContext(context)
|
||||
for k, v in pairs(context) do
|
||||
if type(k) == 'number' then
|
||||
@@ -36,9 +62,11 @@ function lib.registerContext(context)
|
||||
end
|
||||
end
|
||||
|
||||
---@return string?
|
||||
function lib.getOpenContextMenu() return openContextMenu end
|
||||
|
||||
function lib.hideContext(onExit) return closeContext(nil, nil, onExit) end
|
||||
---@param onExit boolean?
|
||||
function lib.hideContext(onExit) closeContext(nil, nil, onExit) end
|
||||
|
||||
RegisterNUICallback('openContext', function(id, cb)
|
||||
cb(1)
|
||||
@@ -64,4 +92,4 @@ RegisterNUICallback('clickContext', function(id, cb)
|
||||
})
|
||||
end)
|
||||
|
||||
RegisterNUICallback('closeContext', closeContext)
|
||||
RegisterNUICallback('closeContext', closeContext)
|
||||
@@ -1,33 +1,49 @@
|
||||
local input
|
||||
|
||||
---@class InputDialogRowProps
|
||||
---@field type 'input' | 'number' | 'checkbox' | 'select' | 'slider'
|
||||
---@field label string
|
||||
---@field options? { value: string, label: string, default?: string }[]
|
||||
---@field password? boolean
|
||||
---@field icon? string
|
||||
---@field iconColor? string
|
||||
---@field placeholder? string
|
||||
---@field default? string | number
|
||||
---@field checked? boolean
|
||||
---@field min? number
|
||||
---@field max? number
|
||||
---@field step? number
|
||||
|
||||
---@param heading string
|
||||
---@param rows string[] | InputDialogRowProps[]
|
||||
---@return string[] | number[] | boolean[] | nil
|
||||
function lib.inputDialog(heading, rows)
|
||||
if input then return end
|
||||
input = promise.new()
|
||||
if input then return end
|
||||
input = promise.new()
|
||||
|
||||
-- Backwards compat with string tables
|
||||
for i = 1, #rows do
|
||||
if type(rows[i]) == 'string' then
|
||||
rows[i] = {type = 'input', label = rows[i]}
|
||||
end
|
||||
-- Backwards compat with string tables
|
||||
for i = 1, #rows do
|
||||
if type(rows[i]) == 'string' then
|
||||
rows[i] = { type = 'input', label = rows[i] --[[@as string]] }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
SetNuiFocus(true, true)
|
||||
SendNUIMessage({
|
||||
action = 'openDialog',
|
||||
data = {
|
||||
heading = heading,
|
||||
rows = rows
|
||||
}
|
||||
})
|
||||
|
||||
SetNuiFocus(true, true)
|
||||
SendNUIMessage({
|
||||
action = 'openDialog',
|
||||
data = {
|
||||
heading = heading,
|
||||
rows = rows
|
||||
}
|
||||
})
|
||||
|
||||
return Citizen.Await(input)
|
||||
return Citizen.Await(input)
|
||||
end
|
||||
|
||||
RegisterNUICallback('inputData', function(data, cb)
|
||||
cb(1)
|
||||
SetNuiFocus(false, false)
|
||||
local promise = input
|
||||
input = nil
|
||||
promise:resolve(data)
|
||||
end)
|
||||
cb(1)
|
||||
SetNuiFocus(false, false)
|
||||
local promise = input
|
||||
input = nil
|
||||
promise:resolve(data)
|
||||
end)
|
||||
@@ -2,139 +2,169 @@ local registeredMenus = {}
|
||||
local openMenu = nil
|
||||
local keepInput = IsNuiFocusKeepingInput()
|
||||
|
||||
---@alias MenuPosition 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
||||
---@alias MenuChangeFunction fun(selected: number, scrollIndex?: number, args?: any)
|
||||
|
||||
---@class MenuOptions
|
||||
---@field label string
|
||||
---@field icon? string
|
||||
---@field values? string[]
|
||||
---@field description? string
|
||||
---@field defaultIndex? number
|
||||
---@field args? any
|
||||
|
||||
---@class MenuProps
|
||||
---@field id string
|
||||
---@field title string
|
||||
---@field options MenuOptions[]
|
||||
---@field position? MenuPosition
|
||||
---@field disableInput? boolean
|
||||
---@field onClose? fun()
|
||||
---@field onSelected? MenuChangeFunction
|
||||
---@field onSideScroll? MenuChangeFunction
|
||||
|
||||
---@param data MenuProps
|
||||
---@param cb? MenuChangeFunction
|
||||
function lib.registerMenu(data, cb)
|
||||
if not data.id then return error('No menu id was provided.') end
|
||||
if not data.title then return error('No menu title was provided.') end
|
||||
if not data.options then return error('No menu options were provided.') end
|
||||
data.cb = cb
|
||||
registeredMenus[data.id] = data
|
||||
if not data.id then error('No menu id was provided.') end
|
||||
if not data.title then error('No menu title was provided.') end
|
||||
if not data.options then error('No menu options were provided.') end
|
||||
data.cb = cb
|
||||
registeredMenus[data.id] = data
|
||||
end
|
||||
|
||||
---@param id string
|
||||
---@param startIndex? number
|
||||
function lib.showMenu(id, startIndex)
|
||||
local menu = registeredMenus[id]
|
||||
local menu = registeredMenus[id]
|
||||
|
||||
if not menu then
|
||||
return error(('No menu with id %s was found'):format(id))
|
||||
end
|
||||
if not menu then
|
||||
error(('No menu with id %s was found'):format(id))
|
||||
end
|
||||
|
||||
if not openMenu then
|
||||
CreateThread(function()
|
||||
while openMenu do
|
||||
if not openMenu.disableInput then
|
||||
DisablePlayerFiring(cache.playerId, true)
|
||||
HudWeaponWheelIgnoreSelection()
|
||||
DisableControlAction(0, 140, true)
|
||||
end
|
||||
if not openMenu then
|
||||
CreateThread(function()
|
||||
while openMenu do
|
||||
if not openMenu.disableInput then
|
||||
DisablePlayerFiring(cache.playerId, true)
|
||||
HudWeaponWheelIgnoreSelection()
|
||||
DisableControlAction(0, 140, true)
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
openMenu = menu
|
||||
keepInput = IsNuiFocusKeepingInput()
|
||||
openMenu = menu
|
||||
keepInput = IsNuiFocusKeepingInput()
|
||||
|
||||
if not menu.disableInput then
|
||||
SetNuiFocusKeepInput(true)
|
||||
end
|
||||
if not menu.disableInput then
|
||||
SetNuiFocusKeepInput(true)
|
||||
end
|
||||
|
||||
SetNuiFocus(true, false)
|
||||
SendNUIMessage({
|
||||
action = 'setMenu',
|
||||
data = {
|
||||
position = menu.position,
|
||||
canClose = menu.canClose,
|
||||
title = menu.title,
|
||||
items = menu.options,
|
||||
startItemIndex = startIndex and startIndex - 1 or 0
|
||||
}
|
||||
})
|
||||
SetNuiFocus(true, false)
|
||||
SendNUIMessage({
|
||||
action = 'setMenu',
|
||||
data = {
|
||||
position = menu.position,
|
||||
canClose = menu.canClose,
|
||||
title = menu.title,
|
||||
items = menu.options,
|
||||
startItemIndex = startIndex and startIndex - 1 or 0
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
local function resetFocus()
|
||||
SetNuiFocus(false, false)
|
||||
SetNuiFocusKeepInput(keepInput)
|
||||
SetNuiFocus(false, false)
|
||||
SetNuiFocusKeepInput(keepInput)
|
||||
end
|
||||
|
||||
---@param onExit boolean?
|
||||
function lib.hideMenu(onExit)
|
||||
local menu = openMenu
|
||||
openMenu = nil
|
||||
local menu = openMenu
|
||||
openMenu = nil
|
||||
|
||||
if onExit and menu.onClose then
|
||||
menu.onClose()
|
||||
end
|
||||
if onExit and menu.onClose then
|
||||
menu.onClose()
|
||||
end
|
||||
|
||||
resetFocus()
|
||||
SendNUIMessage({
|
||||
action = 'closeMenu'
|
||||
})
|
||||
resetFocus()
|
||||
SendNUIMessage({
|
||||
action = 'closeMenu'
|
||||
})
|
||||
end
|
||||
|
||||
---@param id string
|
||||
---@param options MenuOptions | MenuOptions[]
|
||||
---@param index? number
|
||||
function lib.setMenuOptions(id, options, index)
|
||||
if index then
|
||||
registeredMenus[id].options[index] = options
|
||||
else
|
||||
if not options[1] then return error('Invalid override format used, expected table of options.') end
|
||||
registeredMenus[id].options = options
|
||||
end
|
||||
if index then
|
||||
registeredMenus[id].options[index] = options
|
||||
else
|
||||
if not options[1] then error('Invalid override format used, expected table of options.') end
|
||||
registeredMenus[id].options = options
|
||||
end
|
||||
end
|
||||
|
||||
---@return string?
|
||||
function lib.getOpenMenu() return openMenu end
|
||||
|
||||
RegisterNUICallback('confirmSelected', function(data, cb)
|
||||
cb(1)
|
||||
data[1] += 1 -- selected
|
||||
cb(1)
|
||||
data[1] += 1 -- selected
|
||||
|
||||
if data[2] then
|
||||
data[2] += 1 -- scrollIndex
|
||||
end
|
||||
if data[2] then
|
||||
data[2] += 1 -- scrollIndex
|
||||
end
|
||||
|
||||
local menu = openMenu
|
||||
local menu = openMenu
|
||||
|
||||
if menu.options[data[1]].close ~= false then
|
||||
resetFocus()
|
||||
openMenu = nil
|
||||
end
|
||||
if menu.options[data[1]].close ~= false then
|
||||
resetFocus()
|
||||
openMenu = nil
|
||||
end
|
||||
|
||||
if menu.cb then
|
||||
menu.cb(data[1], data[2], menu.options[data[1]].args)
|
||||
end
|
||||
if menu.cb then
|
||||
menu.cb(data[1], data[2], menu.options[data[1]].args)
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNUICallback('changeIndex', function(data, cb)
|
||||
cb(1)
|
||||
if not openMenu.onSideScroll then return end
|
||||
cb(1)
|
||||
if not openMenu.onSideScroll then return end
|
||||
|
||||
data[1] += 1 -- selected
|
||||
data[1] += 1 -- selected
|
||||
|
||||
if data[2] then
|
||||
data[2] += 1 -- scrollIndex
|
||||
end
|
||||
if data[2] then
|
||||
data[2] += 1 -- scrollIndex
|
||||
end
|
||||
|
||||
openMenu.onSideScroll(data[1], data[2], openMenu.options[data[1]].args)
|
||||
openMenu.onSideScroll(data[1], data[2], openMenu.options[data[1]].args)
|
||||
end)
|
||||
|
||||
RegisterNUICallback('changeSelected', function(data, cb)
|
||||
cb(1)
|
||||
if not openMenu.onSelected then return end
|
||||
cb(1)
|
||||
if not openMenu.onSelected then return end
|
||||
|
||||
data[1] += 1 -- selected
|
||||
data[1] += 1 -- selected
|
||||
|
||||
if data[2] then
|
||||
data[2] += 1 -- scrollIndex
|
||||
end
|
||||
if data[2] then
|
||||
data[2] += 1 -- scrollIndex
|
||||
end
|
||||
|
||||
openMenu.onSelected(data[1], data[2], openMenu.options[data[1]].args)
|
||||
openMenu.onSelected(data[1], data[2], openMenu.options[data[1]].args)
|
||||
end)
|
||||
|
||||
RegisterNUICallback('closeMenu', function(data, cb)
|
||||
cb(1)
|
||||
resetFocus()
|
||||
cb(1)
|
||||
resetFocus()
|
||||
|
||||
local menu = openMenu
|
||||
openMenu = nil
|
||||
local menu = openMenu
|
||||
openMenu = nil
|
||||
|
||||
if menu.onClose then
|
||||
menu.onClose()
|
||||
end
|
||||
end)
|
||||
if menu.onClose then
|
||||
menu.onClose()
|
||||
end
|
||||
end)
|
||||
@@ -1,32 +1,40 @@
|
||||
--[[```lua
|
||||
{
|
||||
id?: string
|
||||
title?: string
|
||||
description: string
|
||||
duration?: number
|
||||
position?: 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'
|
||||
style?: table
|
||||
icon?: string
|
||||
iconColor?: string
|
||||
}
|
||||
```]]
|
||||
---@alias NotificationPosition 'top' | 'top-right' | 'top-left' | 'bottom' | 'bottom-right' | 'bottom-left'
|
||||
---@alias NotificationType 'inform' | 'error' | 'success'
|
||||
|
||||
-- Custom notifications with a lot of allowed styling
|
||||
---@param data table
|
||||
---@class NotifyProps
|
||||
---@field id? string
|
||||
---@field title? string
|
||||
---@field description? string
|
||||
---@field duration? number
|
||||
---@field position? NotificationPosition
|
||||
---@field type? NotificationType
|
||||
---@field style? string
|
||||
---@field icon? string;
|
||||
---@field iconColor? string;
|
||||
|
||||
---@param data NotifyProps
|
||||
function lib.notify(data)
|
||||
SendNUIMessage({
|
||||
action = 'customNotify',
|
||||
data = data
|
||||
})
|
||||
SendNUIMessage({
|
||||
action = 'customNotify',
|
||||
data = data
|
||||
})
|
||||
end
|
||||
|
||||
-- Default Chakra UI notifications
|
||||
---@class DefaultNotifyProps
|
||||
---@field title? string
|
||||
---@field description? string
|
||||
---@field duration? number
|
||||
---@field position? NotificationPosition
|
||||
---@field status? 'info' | 'warning' | 'success' | 'error'
|
||||
---@field id? number
|
||||
|
||||
---@param data DefaultNotifyProps
|
||||
function lib.defaultNotify(data)
|
||||
SendNUIMessage({
|
||||
action = 'notify',
|
||||
data = data
|
||||
})
|
||||
SendNUIMessage({
|
||||
action = 'notify',
|
||||
data = data
|
||||
})
|
||||
end
|
||||
|
||||
RegisterNetEvent('ox_lib:notify', lib.notify)
|
||||
RegisterNetEvent('ox_lib:defaultNotify', lib.defaultNotify)
|
||||
RegisterNetEvent('ox_lib:defaultNotify', lib.defaultNotify)
|
||||
@@ -3,169 +3,193 @@ local DisableControlAction = DisableControlAction
|
||||
local DisablePlayerFiring = DisablePlayerFiring
|
||||
local playerState = LocalPlayer.state
|
||||
|
||||
---@class ProgressPropProps
|
||||
---@field model string
|
||||
---@field bone? number
|
||||
---@field pos vector3
|
||||
---@field rot vector3
|
||||
|
||||
---@class ProgressProps
|
||||
---@field label? string
|
||||
---@field duration number
|
||||
---@field position? 'middle' | 'bottom'
|
||||
---@field useWhileDead? boolean
|
||||
---@field allowRagdoll? boolean
|
||||
---@field allowCuffed? boolean
|
||||
---@field allowFalling? boolean
|
||||
---@field canCancel? boolean
|
||||
---@field anim? { dict?: string, clip: string, flag?: number, blendIn?: number, blendOut?: number, duration?: number, playbackRate?: number, lockX?: boolean, lockY?: boolean, lockZ?: boolean, scenario?: string, playEnter?: boolean }
|
||||
---@field prop? ProgressPropProps | ProgressPropProps[]
|
||||
---@field disable? { move?: boolean, car?: boolean, combat?: boolean, mouse?: boolean }
|
||||
|
||||
local function createProp(prop)
|
||||
lib.requestModel(prop.model)
|
||||
local coords = GetEntityCoords(cache.ped)
|
||||
local object = CreateObject(prop.model, coords.x, coords.y, coords.z, true, true, true)
|
||||
AttachEntityToEntity(object, cache.ped, GetPedBoneIndex(cache.ped, prop.bone or 60309), prop.pos.x, prop.pos.y, prop.pos.z, prop.rot.x, prop.rot.y, prop.rot.z, true, true, false, true, 0, true)
|
||||
return object
|
||||
lib.requestModel(prop.model)
|
||||
local coords = GetEntityCoords(cache.ped)
|
||||
local object = CreateObject(prop.model, coords.x, coords.y, coords.z, true, true, true)
|
||||
AttachEntityToEntity(object, cache.ped, GetPedBoneIndex(cache.ped, prop.bone or 60309), prop.pos.x, prop.pos.y, prop.pos.z, prop.rot.x, prop.rot.y, prop.rot.z, true, true, false, true, 0, true)
|
||||
return object
|
||||
end
|
||||
|
||||
local function interruptProgress(data)
|
||||
if not data.useWhileDead and IsEntityDead(cache.ped) then return true end
|
||||
if not data.allowRagdoll and IsPedRagdoll(cache.ped) then return true end
|
||||
if not data.allowCuffed and IsPedCuffed(cache.ped) then return true end
|
||||
if not data.allowFalling and IsPedFalling(cache.ped) then return true end
|
||||
if not data.useWhileDead and IsEntityDead(cache.ped) then return true end
|
||||
if not data.allowRagdoll and IsPedRagdoll(cache.ped) then return true end
|
||||
if not data.allowCuffed and IsPedCuffed(cache.ped) then return true end
|
||||
if not data.allowFalling and IsPedFalling(cache.ped) then return true end
|
||||
end
|
||||
|
||||
local function startProgress(data)
|
||||
playerState.invBusy = true
|
||||
progress = data
|
||||
playerState.invBusy = true
|
||||
progress = data
|
||||
|
||||
if data.anim then
|
||||
if data.anim.dict then
|
||||
lib.requestAnimDict(data.anim.dict)
|
||||
TaskPlayAnim(cache.ped, data.anim.dict, data.anim.clip, data.anim.blendIn or 3.0, data.anim.blendOut or 1.0, data.anim.duration or -1, data.anim.flag or 49, data.anim.playbackRate or 0, data.anim.lockX, data.anim.lockY, data.anim.lockZ)
|
||||
data.anim = true
|
||||
elseif data.anim.scenario then
|
||||
TaskStartScenarioInPlace(cache.ped, data.anim.scenario, 0, data.anim.playEnter ~= nil and data.anim.playEnter or true)
|
||||
data.anim = true
|
||||
end
|
||||
end
|
||||
if data.anim then
|
||||
if data.anim.dict then
|
||||
lib.requestAnimDict(data.anim.dict)
|
||||
TaskPlayAnim(cache.ped, data.anim.dict, data.anim.clip, data.anim.blendIn or 3.0, data.anim.blendOut or 1.0, data.anim.duration or -1, data.anim.flag or 49, data.anim.playbackRate or 0, data.anim.lockX, data.anim.lockY, data.anim.lockZ)
|
||||
data.anim = true
|
||||
elseif data.anim.scenario then
|
||||
TaskStartScenarioInPlace(cache.ped, data.anim.scenario, 0, data.anim.playEnter ~= nil and data.anim.playEnter or true)
|
||||
data.anim = true
|
||||
end
|
||||
end
|
||||
|
||||
if data.prop then
|
||||
if data.prop.model then
|
||||
data.prop1 = createProp(data.prop)
|
||||
else
|
||||
for i = 1, #data.prop do
|
||||
local prop = data.prop[i]
|
||||
if data.prop then
|
||||
if data.prop.model then
|
||||
data.prop1 = createProp(data.prop)
|
||||
else
|
||||
for i = 1, #data.prop do
|
||||
local prop = data.prop[i]
|
||||
|
||||
if prop then
|
||||
data['prop'..i] = createProp(prop)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if prop then
|
||||
data['prop'..i] = createProp(prop)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local disable = data.disable
|
||||
local disable = data.disable
|
||||
|
||||
while progress do
|
||||
if disable then
|
||||
if disable.mouse then
|
||||
DisableControlAction(0, 1, true)
|
||||
DisableControlAction(0, 2, true)
|
||||
DisableControlAction(0, 106, true)
|
||||
end
|
||||
while progress do
|
||||
if disable then
|
||||
if disable.mouse then
|
||||
DisableControlAction(0, 1, true)
|
||||
DisableControlAction(0, 2, true)
|
||||
DisableControlAction(0, 106, true)
|
||||
end
|
||||
|
||||
if disable.move then
|
||||
DisableControlAction(0, 21, true)
|
||||
DisableControlAction(0, 30, true)
|
||||
DisableControlAction(0, 31, true)
|
||||
DisableControlAction(0, 36, true)
|
||||
end
|
||||
if disable.move then
|
||||
DisableControlAction(0, 21, true)
|
||||
DisableControlAction(0, 30, true)
|
||||
DisableControlAction(0, 31, true)
|
||||
DisableControlAction(0, 36, true)
|
||||
end
|
||||
|
||||
if disable.car then
|
||||
DisableControlAction(0, 63, true)
|
||||
DisableControlAction(0, 64, true)
|
||||
DisableControlAction(0, 71, true)
|
||||
DisableControlAction(0, 72, true)
|
||||
DisableControlAction(0, 75, true)
|
||||
end
|
||||
if disable.car then
|
||||
DisableControlAction(0, 63, true)
|
||||
DisableControlAction(0, 64, true)
|
||||
DisableControlAction(0, 71, true)
|
||||
DisableControlAction(0, 72, true)
|
||||
DisableControlAction(0, 75, true)
|
||||
end
|
||||
|
||||
if disable.combat then
|
||||
DisableControlAction(0, 25, true)
|
||||
DisablePlayerFiring(cache.playerId, true)
|
||||
end
|
||||
end
|
||||
if disable.combat then
|
||||
DisableControlAction(0, 25, true)
|
||||
DisablePlayerFiring(cache.playerId, true)
|
||||
end
|
||||
end
|
||||
|
||||
if interruptProgress(progress) then
|
||||
progress = false
|
||||
end
|
||||
if interruptProgress(progress) then
|
||||
progress = false
|
||||
end
|
||||
|
||||
Wait(0)
|
||||
end
|
||||
Wait(0)
|
||||
end
|
||||
|
||||
if data.anim then
|
||||
ClearPedTasks(cache.ped)
|
||||
end
|
||||
if data.anim then
|
||||
ClearPedTasks(cache.ped)
|
||||
end
|
||||
|
||||
if data.prop then
|
||||
local n = #data.prop
|
||||
for i = 1, n > 0 and n or 1 do
|
||||
local prop = data['prop'..i]
|
||||
if data.prop then
|
||||
local n = #data.prop
|
||||
for i = 1, n > 0 and n or 1 do
|
||||
local prop = data['prop'..i]
|
||||
|
||||
if prop then
|
||||
DeleteEntity(prop)
|
||||
end
|
||||
end
|
||||
end
|
||||
if prop then
|
||||
DeleteEntity(prop)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
playerState.invBusy = false
|
||||
local cancel = progress == false
|
||||
progress = nil
|
||||
playerState.invBusy = false
|
||||
local cancel = progress == false
|
||||
progress = nil
|
||||
|
||||
if cancel then
|
||||
SendNUIMessage({ action = 'progressCancel' })
|
||||
return false
|
||||
end
|
||||
if cancel then
|
||||
SendNUIMessage({ action = 'progressCancel' })
|
||||
return false
|
||||
end
|
||||
|
||||
return true
|
||||
return true
|
||||
end
|
||||
|
||||
---@param data ProgressProps
|
||||
---@return boolean?
|
||||
function lib.progressBar(data)
|
||||
while progress ~= nil do Wait(100) end
|
||||
while progress ~= nil do Wait(100) end
|
||||
|
||||
if not interruptProgress(data) then
|
||||
SendNUIMessage({
|
||||
action = 'progress',
|
||||
data = {
|
||||
label = data.label,
|
||||
duration = data.duration
|
||||
}
|
||||
})
|
||||
if not interruptProgress(data) then
|
||||
SendNUIMessage({
|
||||
action = 'progress',
|
||||
data = {
|
||||
label = data.label,
|
||||
duration = data.duration
|
||||
}
|
||||
})
|
||||
|
||||
return startProgress(data)
|
||||
end
|
||||
return startProgress(data)
|
||||
end
|
||||
end
|
||||
|
||||
---@param data ProgressProps
|
||||
---@return boolean?
|
||||
function lib.progressCircle(data)
|
||||
while progress ~= nil do Wait(100) end
|
||||
while progress ~= nil do Wait(100) end
|
||||
|
||||
if not interruptProgress(data) then
|
||||
SendNUIMessage({
|
||||
action = 'circleProgress',
|
||||
data = {
|
||||
duration = data.duration,
|
||||
position = data.position,
|
||||
label = data.label
|
||||
}
|
||||
})
|
||||
if not interruptProgress(data) then
|
||||
SendNUIMessage({
|
||||
action = 'circleProgress',
|
||||
data = {
|
||||
duration = data.duration,
|
||||
position = data.position,
|
||||
label = data.label
|
||||
}
|
||||
})
|
||||
|
||||
return startProgress(data)
|
||||
end
|
||||
return startProgress(data)
|
||||
end
|
||||
end
|
||||
|
||||
function lib.cancelProgress()
|
||||
if not progress then
|
||||
error('No progress bar is active')
|
||||
elseif not progress.canCancel then
|
||||
error('Progress bar cannot be cancelled')
|
||||
end
|
||||
if not progress then
|
||||
error('No progress bar is active')
|
||||
elseif not progress.canCancel then
|
||||
error('Progress bar cannot be cancelled')
|
||||
end
|
||||
|
||||
progress = false
|
||||
progress = false
|
||||
end
|
||||
|
||||
---@return boolean
|
||||
function lib.progressActive()
|
||||
return progress and true
|
||||
return progress and true
|
||||
end
|
||||
|
||||
RegisterNUICallback('progressComplete', function(data, cb)
|
||||
cb(1)
|
||||
progress = nil
|
||||
cb(1)
|
||||
progress = nil
|
||||
end)
|
||||
|
||||
RegisterCommand('cancelprogress', function()
|
||||
if progress?.canCancel then progress = false end
|
||||
if progress?.canCancel then progress = false end
|
||||
end)
|
||||
|
||||
RegisterKeyMapping('cancelprogress', 'Cancel current progress bar', 'keyboard', 'x')
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
---@class TextUIOptions
|
||||
---@field position? 'right-center' | 'left-center' | 'top-center';
|
||||
---@field icon? string;
|
||||
---@field iconColor? string;
|
||||
---@field style? string;
|
||||
|
||||
---@param text string
|
||||
---@param options TextUIOptions
|
||||
function lib.showTextUI(text, options)
|
||||
if not options then options = {} end
|
||||
options.text = text
|
||||
@@ -11,4 +19,4 @@ function lib.hideTextUI()
|
||||
SendNUIMessage({
|
||||
action = 'textUiHide'
|
||||
})
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user