From 6f2acaf116fa9c47e8ae3d1eb2c08888d10e9bfd Mon Sep 17 00:00:00 2001 From: Kasey FItton Date: Thu, 24 Oct 2024 17:19:08 +0100 Subject: [PATCH] feat(es_extended/client/functions): annoations --- [core]/es_extended/client/functions.lua | 191 +++++++++++++++++++++++- [core]/es_extended/client/main.lua | 7 +- [core]/esx_menu_default/client/main.lua | 13 ++ [core]/esx_menu_dialog/client/main.lua | 12 ++ [core]/esx_menu_list/client/main.lua | 9 ++ 5 files changed, 219 insertions(+), 13 deletions(-) diff --git a/[core]/es_extended/client/functions.lua b/[core]/es_extended/client/functions.lua index aab803ec..f0917a01 100644 --- a/[core]/es_extended/client/functions.lua +++ b/[core]/es_extended/client/functions.lua @@ -17,6 +17,10 @@ local function IsResourceFound(resource) return addonResourcesState[resource] or error(('Resource [^5%s^1] is Missing!'):format(resource)) end + +---@param items string | table The item(s) to search for +---@param count? boolean Whether to return the count of the item as well +---@return table | number function ESX.SearchInventory(items, count) local item if type(items) == 'string' then @@ -40,6 +44,9 @@ function ESX.SearchInventory(items, count) return not item and data or data[item] end +---@param key string Table key to set +---@param val any Value to set +---@return nil function ESX.SetPlayerData(key, val) local current = ESX.PlayerData[key] ESX.PlayerData[key] = val @@ -50,6 +57,8 @@ function ESX.SetPlayerData(key, val) end end +---@param freeze boolean Whether to freeze the player +---@return nil function Core.FreezePlayer(freeze) local player = PlayerId() local ped = PlayerPedId() @@ -64,7 +73,10 @@ function Core.FreezePlayer(freeze) end end - +---@param skin table Skin data to set +---@param coords table Coords to spawn the player at +---@param cb function Callback function +---@return nil function ESX.SpawnPlayer(skin, coords, cb) local p = promise.new() TriggerEvent("skinchanger:loadSkin", skin, function() @@ -91,11 +103,14 @@ function ESX.SpawnPlayer(skin, coords, cb) cb() end - function ESX.Progressbar(...) return IsResourceFound('esx_progressbar') and exports['esx_progressbar']:Progressbar(...) end +---@param message string The message to show +---@param notifyType? string The type of notification to show +---@param length? number The length of the notification +---@return nil function ESX.ShowNotification(message, notifyType, length) return IsResourceFound('esx_notify') and exports['esx_notify']:Notify(notifyType, length, message) end @@ -104,10 +119,20 @@ function ESX.TextUI(...) return IsResourceFound('esx_textui') and exports['esx_textui']:TextUI(...) end +---@return nil function ESX.HideUI() return IsResourceFound('esx_textui') and exports['esx_textui']:HideUI() end +---@param sender string +---@param subject string +---@param msg string +---@param textureDict string +---@param iconType integer +---@param flash boolean +---@param saveToBrief? boolean +---@param hudColorIndex? integer +---@return nil function ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) AddTextEntry("esxAdvancedNotification", msg) BeginTextCommandThefeedPost("esxAdvancedNotification") @@ -118,6 +143,11 @@ function ESX.ShowAdvancedNotification(sender, subject, msg, textureDict, iconTyp EndTextCommandThefeedPostTicker(flash, saveToBrief == nil or saveToBrief) end +---@param msg string The message to show +---@param thisFrame? boolean Whether to show the message this frame +---@param beep? boolean Whether to beep +---@param duration? number The duration of the message +---@return nil function ESX.ShowHelpNotification(msg, thisFrame, beep, duration) AddTextEntry("esxHelpNotification", msg) if thisFrame then @@ -128,6 +158,9 @@ function ESX.ShowHelpNotification(msg, thisFrame, beep, duration) end end +---@param msg string The message to show +---@param coords table The coords to show the message at +---@return nil function ESX.ShowFloatingHelpNotification(msg, coords) AddTextEntry("esxFloatingHelpNotification", msg) SetFloatingHelpTextWorldPosition(1, coords.x, coords.y, coords.z) @@ -136,6 +169,9 @@ function ESX.ShowFloatingHelpNotification(msg, coords) EndTextCommandDisplayHelp(2, false, false, -1) end +---@param msg string The message to show +---@param time number The duration of the message +---@return nil function ESX.DrawMissionText(msg, time) ClearPrints() BeginTextCommandPrint('STRING') @@ -143,6 +179,8 @@ function ESX.DrawMissionText(msg, time) EndTextCommandPrint(time, true) end +---@param str string The string to hash +---@return string The hashed string function ESX.HashString(str) return ('~INPUT_%s~'):format(('%x'):format(joaat(str) & 0x7fffffff + 2 ^ 31):upper()) end @@ -163,6 +201,12 @@ function ESX.RefreshContext(...) return IsResourceFound('esx_context') and exports['esx_context']:Refresh(...) end +---@param command_name string The command name +---@param label string The label to show +---@param input_group string The input group +---@param key string The key to bind +---@param on_press function The function to call on press +---@param on_release? function The function to call on release function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_release) local command = on_release and '+' .. command_name or command_name RegisterCommand(command, on_press, false) @@ -173,6 +217,9 @@ function ESX.RegisterInput(command_name, label, input_group, key, on_press, on_r RegisterKeyMapping(command, label or '', input_group or 'keyboard', key or '') end +---@param menuType string +---@param open function The function to call on open +---@param close function The function to call on close function ESX.UI.Menu.RegisterType(menuType, open, close) ESX.UI.Menu.RegisteredTypes[menuType] = { open = open, @@ -180,7 +227,34 @@ function ESX.UI.Menu.RegisterType(menuType, open, close) } end +---@class ESXMenu +---@field type string +---@field namespace string +---@field resourceName string +---@field name string +---@field data table +---@field submit? function +---@field cancel? function +---@field change? function +---@field close function +---@field update function +---@field refresh function +---@field setElement function +---@field setElements function +---@field setTitle function +---@field removeElement function + +---@param menuType string +---@param namespace string +---@param name string +---@param data table +---@param submit? function +---@param cancel? function +---@param change? function +---@param close? function +---@return ESXMenu function ESX.UI.Menu.Open(menuType, namespace, name, data, submit, cancel, change, close) + ---@class ESXMenu local menu = {} menu.type = menuType @@ -261,6 +335,11 @@ function ESX.UI.Menu.Open(menuType, namespace, name, data, submit, cancel, chang return menu end +---@param menuType string +---@param namespace string +---@param name string +---@param cancel? boolean Should the close be classified as a cancel +---@return nil function ESX.UI.Menu.Close(menuType, namespace, name, cancel) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then @@ -276,6 +355,8 @@ function ESX.UI.Menu.Close(menuType, namespace, name, cancel) end end +---@param cancel? boolean Should the close be classified as a cancel +---@return nil function ESX.UI.Menu.CloseAll(cancel) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then @@ -289,6 +370,10 @@ function ESX.UI.Menu.CloseAll(cancel) end end +---@param menuType string +---@param namespace string +---@param name string +---@return ESXMenu | nil function ESX.UI.Menu.GetOpened(menuType, namespace, name) for i = 1, #ESX.UI.Menu.Opened, 1 do if ESX.UI.Menu.Opened[i] then @@ -299,12 +384,17 @@ function ESX.UI.Menu.GetOpened(menuType, namespace, name) end end +---@return ESXMenu[] function ESX.UI.Menu.GetOpenedMenus() return ESX.UI.Menu.Opened end ESX.UI.Menu.IsOpen = ESX.UI.Menu.GetOpened +---@param add boolean Whether the item is being added or removed +---@param item string The item to show +---@param count number How many of the item to show +---@return nil function ESX.UI.ShowInventoryItemNotification(add, item, count) SendNUIMessage({ action = "inventoryNotification", @@ -314,6 +404,8 @@ function ESX.UI.ShowInventoryItemNotification(add, item, count) }) end +---@param ped integer The ped to get the mugshot of +---@param transparent? boolean Whether the mugshot should be transparent function ESX.Game.GetPedMugshot(ped, transparent) if not DoesEntityExist(ped) then return @@ -327,17 +419,19 @@ function ESX.Game.GetPedMugshot(ped, transparent) return mugshot, GetPedheadshotTxdString(mugshot) end +---@param entity integer The entity to get the coords of +---@param coords table | vector3 | vector4 The coords to teleport the entity to +---@param cb? function The callback function function ESX.Game.Teleport(entity, coords, cb) - local vector = type(coords) == "vector4" and coords or type(coords) == "vector3" and vector4(coords, 0.0) or vec(coords.x, coords.y, coords.z, coords.heading or 0.0) if DoesEntityExist(entity) then - RequestCollisionAtCoord(vector.x, vector.y, vector.z) + RequestCollisionAtCoord(coords.x, coords.y, coords.z) while not HasCollisionLoadedAroundEntity(entity) do Wait(0) end - SetEntityCoords(entity, vector.x, vector.y, vector.z, false, false, false, false) - SetEntityHeading(entity, vector.w) + SetEntityCoords(entity, coords.x, coords.y, coords.z, false, false, false, false) + SetEntityHeading(entity, coords.w or coords.heading or 0.0) end if cb then @@ -345,6 +439,11 @@ function ESX.Game.Teleport(entity, coords, cb) end end +---@param object integer | string The object to spawn +---@param coords table | vector3 The coords to spawn the object at +---@param cb? function The callback function +---@param networked? boolean Whether the object should be networked +---@return integer | nil function ESX.Game.SpawnObject(object, coords, cb, networked) local model = type(object) == "number" and object or joaat(object) @@ -354,24 +453,38 @@ function ESX.Game.SpawnObject(object, coords, cb, networked) return cb and cb(obj) or obj end +---@param object integer | string The object to spawn +---@param coords table | vector3 The coords to spawn the object at +---@param cb? function The callback function +---@return nil function ESX.Game.SpawnLocalObject(object, coords, cb) ESX.Game.SpawnObject(object, coords, cb, false) end +---@param vehicle integer The vehicle to delete +---@return nil function ESX.Game.DeleteVehicle(vehicle) SetEntityAsMissionEntity(vehicle, true, true) DeleteVehicle(vehicle) end +---@param object integer The object to delete +---@return nil function ESX.Game.DeleteObject(object) SetEntityAsMissionEntity(object, false, true) DeleteObject(object) end +---@param vehicleModel integer | string The vehicle to spawn +---@param coords table | vector3 The coords to spawn the vehicle at +---@param heading number The heading of the vehicle +---@param cb? function The callback function +---@param networked? boolean Whether the vehicle should be networked +---@return nil function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) local model = type(vehicleModel) == "number" and vehicleModel or joaat(vehicleModel) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) - networked = networked == nil and true or networked + local isNetworked = networked == nil or networked local playerCoords = GetEntityCoords(ESX.PlayerData.ped) if not vector or not playerCoords then @@ -387,7 +500,7 @@ function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) CreateThread(function() ESX.Streaming.RequestModel(model) - local vehicle = CreateVehicle(model, vector.x, vector.y, vector.z, heading, networked, true) + local vehicle = CreateVehicle(model, vector.x, vector.y, vector.z, heading, isNetworked, true) if networked then local id = NetworkGetNetworkIdFromEntity(vehicle) @@ -410,18 +523,28 @@ function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) end) end +---@param vehicle integer The vehicle to spawn +---@param coords table | vector3 The coords to spawn the vehicle at +---@param heading number The heading of the vehicle +---@param cb? function The callback function +---@return nil function ESX.Game.SpawnLocalVehicle(vehicle, coords, heading, cb) ESX.Game.SpawnVehicle(vehicle, coords, heading, cb, false) end +---@param vehicle integer The vehicle to check +---@return boolean function ESX.Game.IsVehicleEmpty(vehicle) return GetVehicleNumberOfPassengers(vehicle) == 0 and IsVehicleSeatFree(vehicle, -1) end +---@return table function ESX.Game.GetObjects() -- Leave the function for compatibility return GetGamePool("CObject") end +---@param onlyOtherPeds? boolean Whether to exlude the player ped +---@return table function ESX.Game.GetPeds(onlyOtherPeds) local pool = GetGamePool("CPed") @@ -438,10 +561,15 @@ function ESX.Game.GetPeds(onlyOtherPeds) return pool end +---@return table function ESX.Game.GetVehicles() -- Leave the function for compatibility return GetGamePool("CVehicle") end +---@param onlyOtherPlayers? boolean Whether to exclude the player +---@param returnKeyValue? boolean Whether to return the key value pair +---@param returnPeds? boolean Whether to return the peds +---@return table function ESX.Game.GetPlayers(onlyOtherPlayers, returnKeyValue, returnPeds) local players, myPlayer = {}, PlayerId() local active = GetActivePlayers() @@ -462,22 +590,38 @@ function ESX.Game.GetPlayers(onlyOtherPlayers, returnKeyValue, returnPeds) return players end +---@param coords? table | vector3 The coords to get the closest object to +---@param modelFilter? table The model filter +---@return integer, integer function ESX.Game.GetClosestObject(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetObjects(), false, coords, modelFilter) end +---@param coords? table | vector3 The coords to get the closest ped to +---@param modelFilter? table The model filter +---@return integer, integer function ESX.Game.GetClosestPed(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetPeds(true), false, coords, modelFilter) end +---@param coords? table | vector3 The coords to get the closest player to +---@return integer, integer function ESX.Game.GetClosestPlayer(coords) return ESX.Game.GetClosestEntity(ESX.Game.GetPlayers(true, true), true, coords, nil) end +---@param coords? table | vector3 The coords to get the closest vehicle to +---@param modelFilter? table The model filter +---@return integer, integer function ESX.Game.GetClosestVehicle(coords, modelFilter) return ESX.Game.GetClosestEntity(ESX.Game.GetVehicles(), false, coords, modelFilter) end +---@param entities table The entities to search through +---@param isPlayerEntities boolean Whether the entities are players +---@param coords table | vector3 The coords to search from +---@param maxDistance number The max distance to search within +---@return table local function EnumerateEntitiesWithinDistance(entities, isPlayerEntities, coords, maxDistance) local nearbyEntities = {} @@ -499,18 +643,29 @@ local function EnumerateEntitiesWithinDistance(entities, isPlayerEntities, coord return nearbyEntities end +---@param coords table | vector3 The coords to search from +---@param maxDistance number The max distance to search within +---@return table function ESX.Game.GetPlayersInArea(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetPlayers(true, true), true, coords, maxDistance) end +---@param coords table | vector3 The coords to search from +---@param maxDistance number The max distance to search within +---@return table function ESX.Game.GetVehiclesInArea(coords, maxDistance) return EnumerateEntitiesWithinDistance(ESX.Game.GetVehicles(), false, coords, maxDistance) end +---@param coords table | vector3 The coords to search from +---@param maxDistance number The max distance to search within +---@return boolean function ESX.Game.IsSpawnPointClear(coords, maxDistance) return #ESX.Game.GetVehiclesInArea(coords, maxDistance) == 0 end +---@param shape integer The shape to get the test result from +---@return boolean, table, table, integer, integer function ESX.Game.GetShapeTestResultSync(shape) local handle, hit, coords, normal, material, entity repeat @@ -520,6 +675,9 @@ function ESX.Game.GetShapeTestResultSync(shape) return hit, coords, normal, material, entity end +---@param depth number The depth to raycast +---@vararg any The arguments to pass to the shape test +---@return table, boolean, table, table, integer, integer function ESX.Game.RaycastScreen(depth, ...) local world, normal = GetWorldCoordFromScreenCoord(.5, .5) local origin = world + normal @@ -527,6 +685,11 @@ function ESX.Game.RaycastScreen(depth, ...) return target, ESX.Game.GetShapeTestResultSync(StartShapeTestLosProbe(origin.x, origin.y, origin.z, target.x, target.y, target.z, ...)) end +---@param entities table The entities to search through +---@param isPlayerEntities boolean Whether the entities are players +---@param coords? table | vector3 The coords to search from +---@param modelFilter? table The model filter +---@return integer, integer function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilter) local closestEntity, closestEntityDistance, filteredEntities = -1, -1, nil @@ -558,6 +721,7 @@ function ESX.Game.GetClosestEntity(entities, isPlayerEntities, coords, modelFilt return closestEntity, closestEntityDistance end +---@return integer | nil, vector3 | nil function ESX.Game.GetVehicleInDirection() local _, hit, coords, _, _, entity = ESX.Game.RaycastScreen(5, 10, ESX.PlayerData.ped) if hit and IsEntityAVehicle(entity) then @@ -565,6 +729,8 @@ function ESX.Game.GetVehicleInDirection() end end +---@param vehicle integer The vehicle to get the properties of +---@return table | nil function ESX.Game.GetVehicleProperties(vehicle) if not DoesEntityExist(vehicle) then return @@ -720,6 +886,9 @@ function ESX.Game.GetVehicleProperties(vehicle) } end +---@param vehicle integer The vehicle to set the properties of +---@param props table The properties to set +---@return nil function ESX.Game.SetVehicleProperties(vehicle, props) if not DoesEntityExist(vehicle) then return @@ -992,6 +1161,11 @@ function ESX.Game.SetVehicleProperties(vehicle, props) end end +---@param coords vector3 | table coords to get the closest pickup to +---@param text string The text to display +---@param size? number The size of the text +---@param font? number The font of the text +---@return nil function ESX.Game.Utils.DrawText3D(coords, text, size, font) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) @@ -1028,6 +1202,7 @@ function ESX.GetAccount(account) return nil end +---@return nil function ESX.ShowInventory() if not Config.EnableDefaultInventory then return diff --git a/[core]/es_extended/client/main.lua b/[core]/es_extended/client/main.lua index 0b0d3dd8..17cc7db2 100644 --- a/[core]/es_extended/client/main.lua +++ b/[core]/es_extended/client/main.lua @@ -501,11 +501,8 @@ if not Config.OxInventory then label = ("%s~n~%s"):format(label, TranslateCap("threw_pickup_prompt")) end - ESX.Game.Utils.DrawText3D({ - x = pickup.coords.x, - y = pickup.coords.y, - z = pickup.coords.z + 0.25, - }, label, 1.2, 1) + local textCoords = pickup.coords + vector3(0.0, 0.0, 0.25) + ESX.Game.Utils.DrawText3D(textCoords, label, 1.2, 1) elseif pickup.inRange then pickup.inRange = false end diff --git a/[core]/esx_menu_default/client/main.lua b/[core]/esx_menu_default/client/main.lua index 522d1a55..95aa4933 100644 --- a/[core]/esx_menu_default/client/main.lua +++ b/[core]/esx_menu_default/client/main.lua @@ -37,6 +37,11 @@ ESX.UI.Menu.RegisterType(MenuType, openMenu, closeMenu) RegisterNUICallback("menu_submit", function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + + if not menu then + return + end + if menu.submit ~= nil then menu.submit(data, menu) end @@ -46,6 +51,10 @@ end) RegisterNUICallback("menu_cancel", function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + if not menu then + return + end + if menu.cancel ~= nil then menu.cancel(data, menu) end @@ -55,6 +64,10 @@ end) RegisterNUICallback("menu_change", function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + if not menu then + return + end + for i = 1, #data.elements, 1 do menu.setElement(i, "value", data.elements[i].value) diff --git a/[core]/esx_menu_dialog/client/main.lua b/[core]/esx_menu_dialog/client/main.lua index f1be462c..abf7a4a3 100644 --- a/[core]/esx_menu_dialog/client/main.lua +++ b/[core]/esx_menu_dialog/client/main.lua @@ -41,6 +41,10 @@ AddEventHandler("esx_menu_dialog:message:menu_submit", function(data) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) local cancel = false + if not menu then + return + end + if menu.submit then -- is the submitted data a number? if tonumber(data.value) then @@ -66,6 +70,10 @@ end) AddEventHandler("esx_menu_dialog:message:menu_cancel", function(data) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + if not menu then + return + end + if menu.cancel ~= nil then menu.cancel(data, menu) end @@ -74,6 +82,10 @@ end) AddEventHandler("esx_menu_dialog:message:menu_change", function(data) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + if not menu then + return + end + if menu.change ~= nil then menu.change(data, menu) end diff --git a/[core]/esx_menu_list/client/main.lua b/[core]/esx_menu_list/client/main.lua index d7fd586b..690c8ef6 100644 --- a/[core]/esx_menu_list/client/main.lua +++ b/[core]/esx_menu_list/client/main.lua @@ -41,6 +41,11 @@ CreateThread(function() RegisterNUICallback("menu_submit", function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + + if not menu then + return + end + if menu.submit then menu.submit(data, menu) end @@ -50,6 +55,10 @@ CreateThread(function() RegisterNUICallback("menu_cancel", function(data, cb) local menu = ESX.UI.Menu.GetOpened(MenuType, data._namespace, data._name) + if not menu then + return + end + if menu.cancel ~= nil then menu.cancel(data, menu) end