diff --git a/[core]/es_extended/server/classes/player.lua b/[core]/es_extended/server/classes/player.lua index 49b600cf..fa8955ab 100644 --- a/[core]/es_extended/server/classes/player.lua +++ b/[core]/es_extended/server/classes/player.lua @@ -1,6 +1,27 @@ -local GetPlayerPed = GetPlayerPed -local GetEntityCoords = GetEntityCoords +local _GetPlayerPed = GetPlayerPed +local _GetEntityCoords = GetEntityCoords +local _ExecuteCommand = ExecuteCommand +local _SetEntityCoords = SetEntityCoords +local _SetEntityHeading = SetEntityHeading +local _TriggerClientEvent = TriggerClientEvent +local _DropPlayer = DropPlayer +local _TriggerEvent = TriggerEvent +local _GiveWeaponToPed = GiveWeaponToPed +local _SetPedAmmo = SetPedAmmo +local _RemoveWeaponFromPed = RemoveWeaponFromPed +local _assert = assert +---@param playerId number +---@param identifier string +---@param group string +---@param accounts table +---@param inventory table +---@param weight number +---@param job table +---@param loadout table +---@param name string +---@param coords table | vector4 +---@param metadata table function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, weight, job, loadout, name, coords, metadata) local targetOverrides = Config.PlayerFunctionOverride and Core.PlayerFunctionOverrides[Config.PlayerFunctionOverride] or {} @@ -23,7 +44,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.admin = Core.IsPlayerAdmin(playerId) if Config.Multichar then self.license = 'license' .. identifier:sub(identifier:find(':'), identifier:len()) else self.license = 'license:' .. identifier end - ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group)) + _ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group)) local stateBag = Player(self.source).state stateBag:set("identifier", self.identifier, true) @@ -33,82 +54,105 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, stateBag:set("name", self.name, true) stateBag:set("metadata", self.metadata, true) + ---@param eventName string + ---@param ... any + ---@return void function self.triggerEvent(eventName, ...) - TriggerClientEvent(eventName, self.source, ...) + _assert(type(eventName) == "string", "eventName should be string!") + _TriggerClientEvent(eventName, self.source, ...) end + ---@param coordinates vector4 | vector3 | table + ---@return void function self.setCoords(coordinates) - local Ped = GetPlayerPed(self.source) - local vector = type(coordinates) == "vector4" and coordinates or type(coordinates) == "vector3" and vector4(coordinates, 0.0) or - vec(coordinates.x, coordinates.y, coordinates.z, coordinates.heading or 0.0) - SetEntityCoords(Ped, vector.xyz, false, false, false, false) - SetEntityHeading(Ped, vector.w) + local ped = _GetPlayerPed(self.source) + local vector = type(coordinates) == "vector4" and coordinates or type(coordinates) == "vector3" and vector4(coordinates, 0.0) or vec(coordinates.x, coordinates.y, coordinates.z, coordinates.heading or 0.0) + _SetEntityCoords(ped, vector.xyz, false, false, false, false) + _SetEntityHeading(ped, vector.w) end + ---@param vector boolean + ---@return vector3 | table function self.getCoords(vector) - local ped = GetPlayerPed(self.source) - local coordinates = GetEntityCoords(ped) + local ped = _GetPlayerPed(self.source) + local coordinates = _GetEntityCoords(ped) + + return vector and coordinates or { x = coordinates.x, y = coordinates.y, z = coordinates.z } - if vector then - return coordinates - else - return { - x = coordinates.x, - y = coordinates.y, - z = coordinates.z, - } - end end + ---@param reason string + ---@return void function self.kick(reason) - DropPlayer(self.source, reason) + _DropPlayer(self.source, reason) end + ---@param money number + ---@return void function self.setMoney(money) + _assert(type(money) == "number", "money should be number!") money = ESX.Math.Round(money) self.setAccountMoney('money', money) end + ---@return number function self.getMoney() return self.getAccount('money').money end + ---@param money number + ---@param reason string + ---@return void function self.addMoney(money, reason) money = ESX.Math.Round(money) self.addAccountMoney('money', money, reason) end + ---@param money number + ---@param reason string + ---@return void function self.removeMoney(money, reason) money = ESX.Math.Round(money) self.removeAccountMoney('money', money, reason) end + ---@return string function self.getIdentifier() return self.identifier end + ---@param newGroup string + ---@return void function self.setGroup(newGroup) - ExecuteCommand(('remove_principal identifier.%s group.%s'):format(self.license, self.group)) + _ExecuteCommand(('remove_principal identifier.%s group.%s'):format(self.license, self.group)) self.group = newGroup Player(self.source).state:set("group", self.group, true) - ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group)) + _ExecuteCommand(('add_principal identifier.%s group.%s'):format(self.license, self.group)) end + ---@return string function self.getGroup() return self.group end + ---@param k string + ---@param v any + ---@return void function self.set(k, v) self.variables[k] = v Player(self.source).state:set(k, v, true) end + ---@param k string + ---@return any function self.get(k) return self.variables[k] end + ---@param minimal boolean + ---@return table function self.getAccounts(minimal) - if not minimal then + if not (minimal) then return self.accounts end @@ -121,6 +165,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return minimalAccounts end + ---@param account string + ---@return table | nil function self.getAccount(account) for i = 1, #self.accounts do if self.accounts[i].name == account then @@ -130,6 +176,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return nil end + ---@param minimal boolean + ---@return table function self.getInventory(minimal) if minimal then local minimalInventory = {} @@ -144,14 +192,18 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end return self.inventory + end + ---@return table function self.getJob() return self.job end + ---@param minimal boolean + ---@return table function self.getLoadout(minimal) - if not minimal then + if not (minimal) then return self.loadout end local minimalLoadout = {} @@ -178,15 +230,22 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return minimalLoadout end + ---@return string function self.getName() return self.name end + ---@param newName string + ---@return void function self.setName(newName) self.name = newName Player(self.source).state:set("name", self.name, true) end + ---@param accountName string + ---@param money number + ---@param reason string + ---@return void function self.setAccountMoney(accountName, money, reason) reason = reason or 'unknown' if not tonumber(money) then @@ -201,7 +260,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.accounts[account.index].money = money self.triggerEvent('esx:setAccountMoney', account) - TriggerEvent('esx:setAccountMoney', self.source, accountName, money, reason) + _TriggerEvent('esx:setAccountMoney', self.source, accountName, money, reason) else print(('[^1ERROR^7] Tried To Set Invalid Account ^5%s^0 For Player ^5%s^0!'):format(accountName, self.playerId)) end @@ -210,6 +269,10 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param accountName string + ---@param money number + ---@param reason string + ---@return void function self.addAccountMoney(accountName, money, reason) reason = reason or 'Unknown' if not tonumber(money) then @@ -223,7 +286,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.accounts[account.index].money = self.accounts[account.index].money + money self.triggerEvent('esx:setAccountMoney', account) - TriggerEvent('esx:addAccountMoney', self.source, accountName, money, reason) + _TriggerEvent('esx:addAccountMoney', self.source, accountName, money, reason) else print(('[^1ERROR^7] Tried To Set Add To Invalid Account ^5%s^0 For Player ^5%s^0!'):format(accountName, self.playerId)) end @@ -232,6 +295,10 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param accountName string + ---@param money number + ---@param reason string + ---@return void function self.removeAccountMoney(accountName, money, reason) reason = reason or 'Unknown' if not tonumber(money) then @@ -246,7 +313,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.accounts[account.index].money = self.accounts[account.index].money - money self.triggerEvent('esx:setAccountMoney', account) - TriggerEvent('esx:removeAccountMoney', self.source, accountName, money, reason) + _TriggerEvent('esx:removeAccountMoney', self.source, accountName, money, reason) else print(('[^1ERROR^7] Tried To Set Add To Invalid Account ^5%s^0 For Player ^5%s^0!'):format(accountName, self.playerId)) end @@ -255,14 +322,20 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param itemName string + ---@return table | nil function self.getInventoryItem(itemName) for _, v in ipairs(self.inventory) do if v.name == itemName then return v end end + return nil end + ---@param itemName string + ---@param count number + ---@return void function self.addInventoryItem(itemName, count) local item = self.getInventoryItem(itemName) @@ -271,11 +344,14 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, item.count = item.count + count self.weight = self.weight + (item.weight * count) - TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) + _TriggerEvent('esx:onAddInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:addInventoryItem', item.name, item.count) end end + ---@param itemName string + ---@param count number + ---@return void function self.removeInventoryItem(itemName, count) local item = self.getInventoryItem(itemName) @@ -288,7 +364,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, item.count = newCount self.weight = self.weight - (item.weight * count) - TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) + _TriggerEvent('esx:onRemoveInventoryItem', self.source, item.name, item.count) self.triggerEvent('esx:removeInventoryItem', item.name, item.count) end else @@ -297,6 +373,9 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param itemName string + ---@param count number + ---@return void function self.setInventoryItem(itemName, count) local item = self.getInventoryItem(itemName) @@ -311,14 +390,19 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@return number function self.getWeight() return self.weight end + ---@return number function self.getMaxWeight() return self.maxWeight end + ---@param itemName string + ---@param count number + ---@return boolean function self.canCarryItem(itemName, count) if ESX.Items[itemName] then local currentWeight, itemWeight = self.weight, ESX.Items[itemName].weight @@ -330,6 +414,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param firstItem string + ---@param firstItemCount number + ---@param testItem string + ---@param testItemCount number + ---@return boolean function self.canSwapItem(firstItem, firstItemCount, testItem, testItemCount) local firstItemObject = self.getInventoryItem(firstItem) local testItemObject = self.getInventoryItem(testItem) @@ -344,14 +433,19 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return false end + ---@param newWeight number + ---@return void function self.setMaxWeight(newWeight) self.maxWeight = newWeight self.triggerEvent('esx:setMaxWeight', self.maxWeight) end + ---@param newJob string + ---@param grade string + ---@return void function self.setJob(newJob, grade) grade = tostring(grade) - local lastJob = json.decode(json.encode(self.job)) + local lastJob = json.decode(json.encode(self.job)) if ESX.DoesJobExist(newJob, grade) then local jobObject, gradeObject = ESX.Jobs[newJob], ESX.Jobs[newJob].grades[grade] @@ -377,7 +471,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, self.job.skin_female = {} end - TriggerEvent('esx:setJob', self.source, self.job, lastJob) + _TriggerEvent('esx:setJob', self.source, self.job, lastJob) self.triggerEvent('esx:setJob', self.job, lastJob) Player(self.source).state:set("job", self.job, true) else @@ -385,9 +479,12 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param weaponName string + ---@param ammo number + ---@return void function self.addWeapon(weaponName, ammo) if not self.hasWeapon(weaponName) then - local weaponLabel = ESX.GetWeaponLabel(weaponName) + local weaponLabel = ESX.GetWeaponLabel(weaponName) table.insert(self.loadout, { name = weaponName, @@ -397,13 +494,16 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, tintIndex = 0 }) - GiveWeaponToPed(GetPlayerPed(self.source), joaat(weaponName), ammo, false, false) + _GiveWeaponToPed(_GetPlayerPed(self.source), joaat(weaponName), ammo, false, false) self.triggerEvent('esx:addInventoryItem', weaponLabel, false, true) end end + ---@param weaponName string + ---@param weaponComponent string + ---@return void function self.addWeaponComponent(weaponName, weaponComponent) - local loadoutNum, weapon = self.getWeapon(weaponName) + local loadoutNum , weapon = self.getWeapon(weaponName) if weapon then local component = ESX.GetWeaponComponent(weaponName, weaponComponent) @@ -419,28 +519,38 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param weaponName string + ---@param ammoCount number + ---@return void function self.addWeaponAmmo(weaponName, ammoCount) local _, weapon = self.getWeapon(weaponName) if weapon then weapon.ammo = weapon.ammo + ammoCount - SetPedAmmo(GetPlayerPed(self.source), joaat(weaponName), weapon.ammo) + _SetPedAmmo(GetPlayerPed(self.source), joaat(weaponName), weapon.ammo) end end + ---@param weaponName string + ---@param ammoCount number + ---@return void function self.updateWeaponAmmo(weaponName, ammoCount) local _, weapon = self.getWeapon(weaponName) if weapon then weapon.ammo = ammoCount end + end + ---@param weaponName string + ---@param weaponTintIndex number + ---@return void function self.setWeaponTint(weaponName, weaponTintIndex) - local loadoutNum, weapon = self.getWeapon(weaponName) + local loadoutNum , weapon = self.getWeapon(weaponName) if weapon then - local _, weaponObject = ESX.GetWeapon(weaponName) + local _, weaponObject = ESX.GetWeapon(weaponName) if weaponObject.tints and weaponObject.tints[weaponTintIndex] then self.loadout[loadoutNum].tintIndex = weaponTintIndex @@ -450,20 +560,27 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param weaponName string + ---@return number function self.getWeaponTint(weaponName) - local _, weapon = self.getWeapon(weaponName) + local _, weapon = self.getWeapon(weaponName) if weapon then return weapon.tintIndex end return 0 + end + ---@param weaponName string + ---@return void function self.removeWeapon(weaponName) - local weaponLabel, playerPed = nil, GetPlayerPed(self.source) + local weaponLabel, playerPed = nil, _GetPlayerPed(self.source) + + + if not playerPed then - if not playerPed then return print("[^1ERROR^7] xPlayer.removeWeapon ^5invalid^7 player ped!") end @@ -476,9 +593,8 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end local weaponHash = joaat(v.name) - - RemoveWeaponFromPed(playerPed, weaponHash) - SetPedAmmo(playerPed, weaponHash, 0) + _RemoveWeaponFromPed(playerPed, weaponHash) + _SetPedAmmo(playerPed, weaponHash, 0) table.remove(self.loadout, k) break @@ -490,11 +606,15 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param weaponName string + ---@param weaponComponent string + ---@return void function self.removeWeaponComponent(weaponName, weaponComponent) - local loadoutNum, weapon = self.getWeapon(weaponName) + local loadoutNum , weapon = self.getWeapon(weaponName) if weapon then - local component = ESX.GetWeaponComponent(weaponName, weaponComponent) + ---@type table + local component = ESX.GetWeaponComponent(weaponName, weaponComponent) if component then if self.hasWeaponComponent(weaponName, weaponComponent) then @@ -512,6 +632,9 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param weaponName string + ---@param ammoCount number + ---@return void function self.removeWeaponAmmo(weaponName, ammoCount) local _, weapon = self.getWeapon(weaponName) @@ -521,8 +644,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end end + ---@param weaponName string + ---@param weaponComponent string + ---@return boolean function self.hasWeaponComponent(weaponName, weaponComponent) - local _, weapon = self.getWeapon(weaponName) + local _, weapon = self.getWeapon(weaponName) if weapon then for _, v in ipairs(weapon.components) do @@ -532,11 +658,15 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end return false - else - return false + end + + return false + end + ---@param weaponName string + ---@return boolean function self.hasWeapon(weaponName) for _, v in ipairs(self.loadout) do if v.name == weaponName then @@ -547,9 +677,11 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return false end + ---@param item string + ---@return table, number | false function self.hasItem(item) for _, v in ipairs(self.inventory) do - if (v.name == item) and (v.count >= 1) then + if v.name == item and v.count >= 1 then return v, v.count end end @@ -557,52 +689,77 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return false end + ---@param weaponName string + ---@return number, table | nil function self.getWeapon(weaponName) for k, v in ipairs(self.loadout) do if v.name == weaponName then return k, v end end + + return nil end + ---@param msg string + ---@param type string + ---@param length number + ---@return void function self.showNotification(msg, notifyType, length) self.triggerEvent('esx:showNotification', msg, notifyType, length) end + ---@param sender string + ---@param subject string + ---@param msg string + ---@param textureDict string + ---@param iconType string + ---@param flash boolean + ---@param saveToBrief boolean + ---@param hudColorIndex number + ---@return void function self.showAdvancedNotification(sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) self.triggerEvent('esx:showAdvancedNotification', sender, subject, msg, textureDict, iconType, flash, saveToBrief, hudColorIndex) end + ---@param msg string + ---@param thisFrame boolean + ---@param beep boolean + ---@param duration number + ---@return void function self.showHelpNotification(msg, thisFrame, beep, duration) self.triggerEvent('esx:showHelpNotification', msg, thisFrame, beep, duration) end + ---@param index any + ---@param subIndex any + ---@return table function self.getMeta(index, subIndex) - if not (index) then return self.metadata end + if not index then return self.metadata end if type(index) ~= "string" then return print("[^1ERROR^7] xPlayer.getMeta ^5index^7 should be ^5string^7!") end local metaData = self.metadata[index] - if (metaData == nil) then + if metaData == nil then return Config.EnableDebug and print(("[^1ERROR^7] xPlayer.getMeta ^5%s^7 not exist!"):format(index)) or nil end - if (subIndex and type(metaData) == "table") then + if subIndex and type(metaData) == "table" then local _type = type(subIndex) - if (_type == "string") then + if _type == "string" then local value = metaData[subIndex] return value end - if (_type == "table") then + if _type == "table" then local returnValues = {} for i = 1, #subIndex do local key = subIndex[i] - if (type(key) == "string") then + if type(key) == "string" then returnValues[key] = self.getMeta(index, key) else print(("[^1ERROR^7] xPlayer.getMeta subIndex should be ^5string^7 or ^5table^7! that contains ^5string^7, received ^5%s^7!, skipping..."):format(type(key))) @@ -618,6 +775,10 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, return metaData end + ---@param index any + ---@param value any + ---@param subValue any + ---@return void function self.setMeta(index, value, subValue) if not index then return print("[^1ERROR^7] xPlayer.setMeta ^5index^7 is Missing!") @@ -655,6 +816,7 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, Player(self.source).state:set('metadata', self.metadata, true) end + function self.clearMeta(index, subValues) if not index then return print("[^1ERROR^7] xPlayer.clearMeta ^5index^7 is Missing!") @@ -705,4 +867,5 @@ function CreateExtendedPlayer(playerId, identifier, group, accounts, inventory, end return self + end