--- Locks or unlocks the player's inventory. --- --- This function freezes or unfreezes the player's position, sets the inventory busy state, --- and toggles the ability to use the inventory and hotbar based on the `toggle` parameter. --- --- @param toggle boolean `true` to lock the inventory, `false` to unlock. --- --- @usage --- ```lua --- -- Lock the player's inventory --- lockInv(true) --- --- -- Unlock the player's inventory --- lockInv(false) --- ``` function lockInv(toggle) FreezeEntityPosition(PlayerPedId(), toggle) LocalPlayer.state:set("inv_busy", toggle, true) TriggerEvent('inventory:client:busy:status', toggle) TriggerEvent('canUseInventoryAndHotbar:toggle', not toggle) end --- Instantly turns an entity to face a specific location or another entity. --- --- This function calculates the heading from the first entity to the second entity or coordinates --- and sets the entity's heading immediately without any animation. --- --- @param ent number|nil The Ped entity to turn. Defaults to the player's Ped (`PlayerPedId()`). --- @param ent2 number|vector3|nil The target entity or coordinates to face. If a vector, it uses the coordinates. --- --- @usage --- ```lua --- -- Make the player instantly face a specific location --- instantLookEnt(nil, vector3(200.0, 300.0, 40.0)) --- --- -- Make one entity face another entity --- instantLookEnt(ped1, ped2) --- ``` function instantLookEnt(ent, ent2) local ent = ent or PlayerPedId() local p1 = GetEntityCoords(ent, true) local p2 = type(ent2):find("vector") and ent2 or GetEntityCoords(ent2, true) local dx = p2.x - p1.x local dy = p2.y - p1.y local heading = GetHeadingFromVector_2d(dx, dy) debugPrint("^6Bridge^7: ^1Forced ^2Turning Player to^7: '^6"..formatCoord(p2).."^7'") SetEntityHeading(ent, heading) end --- Makes the player Ped look towards a specific entity or coordinates with animation. --- --- This function checks if the player is already facing the target. If not, it triggers a turning animation --- to face the specified entity or coordinates. --- --- @param entity number|vector3|vector4|nil The target entity or coordinates to look at. --- --- @usage --- ```lua --- -- Make the player look at a specific location --- lookEnt(vector3(200.0, 300.0, 40.0)) --- --- -- Make the player look at another entity --- lookEnt(pedEntity) --- ``` function lookEnt(entity) local ped = PlayerPedId() if entity then if type(entity) == "vector3" or type(entity) == "vector4" then if not IsPedHeadingTowardsPosition(ped, entity.xyz, 30.0) then TaskTurnPedToFaceCoord(ped, entity.xyz, 1500) debugPrint("^6Bridge^7: ^2Turning Player to^7: '^6"..formatCoord(entity).."^7'") Wait(1500) end else if DoesEntityExist(entity) then local entCoords = GetEntityCoords(entity) if not IsPedHeadingTowardsPosition(ped, entCoords, 30.0) then TaskTurnPedToFaceCoord(ped, entCoords, 1500) debugPrint("^6Bridge^7: ^2Turning Player to^7: '^6"..entity.."^7' - '"..formatCoord(entCoords).."^7'") Wait(1500) end end end end end --- Server event handler for handling urinal usage. --- --- This event decreases the player's thirst based on a random amount and updates their thirst level. --- --- @usage --- ```lua --- -- Triggered when a player uses a urinal --- TriggerServerEvent(getScript()..":server:Urinal") --- ``` RegisterNetEvent(getScript()..":server:Urinal", function() local src = source local Player = getPlayer(src) local thirstamt = math.random(10, 30) local thirst = Player.thirst - thirstamt setThirst(src, getPlayer(src).thirst - thirst) end) --- Server event handler for setting player needs. --- --- This event updates the player's thirst or hunger based on the provided type and amount. --- --- @event --- @param type string The type of need to set ("thirst" or "hunger"). --- @param amount number The amount to set the need to. --- --- @return void --- --- @usage --- ```lua --- -- Set the player's thirst level --- TriggerServerEvent(getScript()..":server:setNeed", "thirst", 50) --- --- -- Set the player's hunger level --- TriggerServerEvent(getScript()..":server:setNeed", "hunger", 75) --- ``` RegisterNetEvent(getScript()..":server:setNeed", function(type, amount) local src = source if type == "thirst" then setThirst(src, amount) elseif type == "hunger" then setHunger(src, amount) end end) --- Sets the player's thirst level. --- --- This function updates the player's thirst based on the active inventory system. --- --- @param src number The server ID of the player. --- @param thirst number The new thirst level to set. --- --- @usage --- ```lua --- -- Set a player's thirst to 80 --- setThirst(playerId, 80) --- ``` function setThirst(src, thirst) if isStarted(ESXExport) then TriggerClientEvent('esx_status:add', src, 'thirst', thirst) elseif isStarted(QBExport) or isStarted(QBXExport) then local Player = Core.Functions.GetPlayer(src) Player.Functions.SetMetaData('thirst', thirst) TriggerClientEvent("hud:client:UpdateNeeds", src, thirst, Player.PlayerData.metadata.thirst) end end --- Sets the player's hunger level. --- --- This function updates the player's hunger based on the active inventory system. --- --- @param src number The server ID of the player. --- @param hunger number The new hunger level to set. --- --- @usage --- ```lua --- -- Set a player's hunger to 60 --- setHunger(playerId, 60) --- ``` function setHunger(src, hunger) if isStarted(ESXExport) then TriggerClientEvent('esx_status:add', src, 'hunger', hunger) elseif isStarted(QBExport) or isStarted(QBXExport) then local Player = Core.Functions.GetPlayer(src) Player.Functions.SetMetaData('hunger', hunger) TriggerClientEvent("hud:client:UpdateNeeds", src, hunger, Player.PlayerData.metadata.hunger) end end --- Server event handler for charging a player. --- --- This event removes money from a player based on the specified type ("cash" or "bank"). --- --- @event --- @param cost number The amount of money to charge. --- @param type string The type of money to charge ("cash" or "bank"). --- @param newsrc number|nil Optional. The server ID of the player. If `nil`, uses the event source. --- --- @usage --- ```lua --- -- Charge a player $100 in cash --- chargePlayer(100, "cash", playerId) --- --- -- Charge the source $250 from the bank --- chargePlayer(250, "bank", src,) --- ``` function chargePlayer(cost, type, newsrc) local src = newsrc or source local fundResource = "" if type == "cash" then if isStarted(OXInv) then fundResource = OXInv exports[OXInv]:RemoveItem(src, "money", cost) elseif isStarted(QBExport) or isStarted(QBXExport) then fundResource = QBExport Core.Functions.GetPlayer(src).Functions.RemoveMoney("cash", cost) elseif isStarted(ESXExport) then fundResource = ESXExport local Player = ESX.GetPlayerFromId(src) Player.removeMoney(cost, "") end end if type == "bank" then if isStarted(QBExport) or isStarted(QBXExport) then fundResource = QBExport Core.Functions.GetPlayer(src).Functions.RemoveMoney("bank", cost) elseif isStarted(ESXExport) then fundResource = ESXExport local Player = ESX.GetPlayerFromId(src) Player.removeMoney(cost, "") end end if fundResource == "" then print("error - check exports.lua") else debugPrint("^6Bridge^7: ^2Charging ^2Player^7: '^6"..cost.."^7'", type, fundResource) end end RegisterNetEvent(getScript()..":server:ChargePlayer", chargePlayer) --- Server event handler for funding a player. --- --- This event adds money to a player based on the specified type ("cash" or "bank"). --- --- @event --- @param fund number The amount of money to add. --- @param type string The type of money to add ("cash" or "bank"). --- @param newsrc number|nil Optional. The server ID of the player. If `nil`, uses the event source. --- --- @usage --- ```lua --- -- Add $150 to a player's cash --- fundPlayer(playerId, 150, "cash") --- --- -- Add $300 to the event source's bank account --- fundPlayer(playerId, 300, "bank") --- ``` function fundPlayer(fund, type, newsrc) local src = newsrc or source local fundResource = "" if type == "cash" then if isStarted(OXInv) then fundResource = OXInv exports[OXInv]:AddItem(src, "money", fund) elseif isStarted(QBExport) or isStarted(QBXExport) then fundResource = QBExport Core.Functions.GetPlayer(src).Functions.AddMoney("cash", fund) elseif isStarted(ESXExport) then fundResource = ESXExport local Player = ESX.GetPlayerFromId(src) Player.addMoney(fund, "") end end if type == "bank" then if isStarted(QBExport) or isStarted(QBXExport) then fundResource = QBExport Core.Functions.GetPlayer(src).Functions.AddMoney("bank", fund) elseif isStarted(ESXExport) then fundResource = ESXExport local Player = ESX.GetPlayerFromId(src) Player.addMoney(fund, "") end end if fundResource == "" then print("error - check exports.lua") else debugPrint("^6Bridge^7: ^2Funding ^2Player^7: '^2"..fund.."^7'", type, fundResource) end end RegisterNetEvent(getScript()..":server:FundPlayer", fundPlayer) --- Handles successful consumption of an item. --- --- This function plays a consumption animation, removes the item from the inventory, --- updates the player's hunger and thirst based on the item consumed, --- handles alcohol effects, and checks for random rewards. --- --- @param itemName string The name of the item consumed. --- @param type string The type/category of the item (e.g., "alcohol"). --- --- @usage --- ```lua --- -- Player consumes a health pack --- ConsumeSuccess("health_pack", "health") --- --- -- Player consumes an alcohol drink --- ConsumeSuccess("beer", "alcohol") --- ``` function ConsumeSuccess(itemName, type, data) local hunger = data and data.hunger or Items[itemName].hunger or nil local thirst = data and data.thirst or Items[itemName].thirst or nil ExecuteCommand("e c") removeItem(itemName, 1) if isStarted(ESXExport) then if hunger then TriggerServerEvent(getScript()..":server:setNeed", "hunger", hunger * 10000) end if thirst then TriggerServerEvent(getScript()..":server:setNeed", "thirst", thirst * 10000) end else if hunger then TriggerServerEvent(getScript()..":server:setNeed", "hunger", Core.Functions.GetPlayerData().metadata["hunger"] + hunger) end if thirst then TriggerServerEvent(getScript()..":server:setNeed", "thirst", Core.Functions.GetPlayerData().metadata["thirst"] + thirst) end end if type == "alcohol" then alcoholCount += 1 if alcoholCount > 1 and alcoholCount < 4 then TriggerEvent("evidence:client:SetStatus", "alcohol", 200) elseif alcoholCount >= 4 then TriggerEvent("evidence:client:SetStatus", "heavyalcohol", 200) AlienEffect() end end getRandomReward(itemName) -- check if a reward item should be given end --- Checks if a player has a specific job and grade. --- --- This function verifies whether the player has the specified job and, if a grade is provided, --- whether the player's grade meets the required level. It supports multiple inventory systems. --- --- @param job string The name of the job or gang to check. --- @param source number|nil Optional. The server ID of the player to check. If `nil`, checks the current player. --- @param grade number|nil Optional. The minimum grade level required. --- --- @return boolean, boolean Returns `true` and `duty status` if the player has the job (and grade if specified), otherwise `false`. --- --- @usage --- ```lua --- -- Check if the player has the 'police' job and is on duty --- local hasPoliceJob, isOnDuty = hasJob("police") --- if hasPoliceJob and isOnDuty then --- -- Grant access to police-specific features --- end --- --- -- Check if a specific player has the 'gang_leader' job with at least grade 2 --- local hasGangLeaderJob, _ = hasJob("gang_leader", playerId, 2) --- if hasGangLeaderJob then --- -- Allow gang leader actions --- end --- ``` function hasJob(job, source, grade) local hasJob, duty = false, true if source then local src = tonumber(source) if not src then print(tostring(source).." is not a valid player source") end if isStarted(ESXExport) then local info = ESX.GetPlayerFromId(src).job while not info do info = ESX.GetPlayerData(src).job Wait(100) end if info.name == job then hasJob = true end elseif isStarted(OXCoreExport) then local chunk = assert(load(LoadResourceFile('ox_core', ('imports/%s.lua'):format('server')), ('@@ox_core/%s'):format(file))) chunk() local player = Ox.GetPlayer(tonumber(src)) for k, v in pairs(player.getGroups()) do if k == job then hasJob = true end end elseif isStarted(QBXExport) then local jobinfo = exports[QBXExport]:GetPlayer(src).PlayerData.job if jobinfo.name == job then hasJob = true duty = exports[QBXExport]:GetPlayer(src).PlayerData.job.onduty if grade and not (grade <= jobinfo.grade.level) then hasJob = false end end local ganginfo = exports[QBXExport]:GetPlayer(src).PlayerData.gang if ganginfo.name == job then hasJob = true if grade and not (grade <= ganginfo.grade.level) then hasJob = false end end elseif isStarted(QBExport) and not isStarted(QBXExport) then if Core.Functions.GetPlayer then -- support older qb-core functions local player = Core.Functions.GetPlayer(src) if not player then print("Player not found for src: "..src) end local jobinfo = player.PlayerData.job if jobinfo.name == job then hasJob = true duty = Core.Functions.GetPlayer(src).PlayerData.job.onduty if grade and not (grade <= jobinfo.grade.level) then hasJob = false end end local ganginfo = Core.Functions.GetPlayer(src).PlayerData.gang if ganginfo.name == job then hasJob = true if grade and not (grade <= ganginfo.grade.level) then hasJob = false end end else -- support newer qb-core exports local jobinfo = exports[QBExport]:GetPlayer(src).PlayerData.job if jobinfo.name == job then hasJob = true duty = exports[QBExport]:GetPlayer(src).PlayerData.job.onduty if grade and not (grade <= jobinfo.grade.level) then hasJob = false end end local ganginfo = exports[QBExport]:GetPlayer(src).PlayerData.gang if ganginfo.name == job then hasJob = true if grade and not (grade <= ganginfo.grade.level) then hasJob = false end end end else print("^4ERROR^7: ^2No Core detected for hasJob ^7- ^2Check ^3exports^1.^2lua^7") end else if isStarted(ESXExport) then while not ESX do Wait(10) end local info = ESX.GetPlayerData().job while not info do info = ESX.GetPlayerData().job Wait(100) end if info.name == job then hasJob = true end elseif isStarted(OXCoreExport) then for k, v in pairs(exports[OXCoreExport]:GetPlayerData().groups) do if k == job then hasJob = true end break end elseif isStarted(QBXExport) then local jobinfo = QBX.PlayerData.job if jobinfo.name == job then hasJob = true duty = QBX.PlayerData.job.onduty if grade and not (grade <= jobinfo.grade.level) then hasJob = false end end local ganginfo = QBX.PlayerData.gang if ganginfo.name == job then hasJob = true if grade and not (grade <= ganginfo.grade.level) then hasJob = false end end elseif isStarted(QBExport) and not isStarted(QBXExport) then local info = nil Core.Functions.GetPlayerData(function(PlayerData) info = PlayerData end) local jobinfo = info.job if jobinfo.name == job then hasJob = true duty = jobinfo.onduty if grade and not (grade <= jobinfo.grade.level) then hasJob = false end end local ganginfo = info.gang if ganginfo.name == job then hasJob = true if grade and not (grade <= ganginfo.grade.level) then hasJob = false end end else print("^4ERROR^7: ^2No Core detected for hasJob() ^7- ^2Check ^3exports^1.^2lua^7") end end return hasJob, duty end --- Retrieves basic information about a player. --- --- This function gathers the player's name, cash balance, and bank balance --- based on the active inventory system. It can be called server-side or client-side. --- ---@param source number|nil Optional. The server ID of the player. If `nil`, retrieves info for the current player. --- ---@return table table A table containing the player's `name`, `cash`, and `bank` balances. --- ---@usage --- ```lua --- -- Get information for a specific player --- local playerInfo = getPlayer(playerId) --- print(playerInfo.name, playerInfo.cash, playerInfo.bank) --- --- -- Get information for the current player (client-side) --- local myInfo = getPlayer() --- print(myInfo.name, myInfo.cash, myInfo.bank) --- ``` function getPlayer(source) local Player = {} debugPrint("^6Bridge^7: ^2Getting ^3Player^2 info^7") if source then -- If called from server local src = tonumber(source) if isStarted(ESXExport) then local info = ESX.GetPlayerFromId(src) Player = { name = info.getName(), cash = info.getMoney(), bank = info.getAccount("bank").money, firstname = info.variables.firstName, lastname = info.variables.lastName, source = info.source, job = info.job.name, --jobBoss = info.job.isboss, --gang = info.gang.name, --gangBoss = info.gang.isboss, onDuty = info.job.onDuty, --account = info.charinfo.account, --citizenId = info.citizenid, } elseif isStarted(OXCoreExport) then local file = ('imports/%s.lua'):format('server') local import = LoadResourceFile('ox_core', file) local chunk = assert(load(import, ('@@ox_core/%s'):format(file))) chunk() local player = Ox.GetPlayer(tonumber(src)) Player = { name = ('%s %s'):format(player.firstName, player.lastName), cash = exports[OXInv]:Search(src, 'count', "money"), bank = 0, } elseif isStarted(QBXExport) then local info = exports[QBXExport]:GetPlayer(src) Player = { firstname = info.PlayerData.charinfo.firstname, lastname = info.PlayerData.charinfo.lastname, name = info.PlayerData.charinfo.firstname.." "..info.PlayerData.charinfo.lastname, cash = exports[OXInv]:Search(src, 'count', "money"), bank = info.Functions.GetMoney("bank"), source = info.PlayerData.source, job = info.PlayerData.job.name, jobBoss = info.PlayerData.job.isboss, gang = info.PlayerData.gang.name, gangBoss = info.PlayerData.gang.isboss, onDuty = info.PlayerData.job.onduty, account = info.PlayerData.charinfo.account, citizenId = info.PlayerData.citizenid, } elseif isStarted(QBExport) and not isStarted(QBXExport) then if Core.Functions.GetPlayer ~= nil then -- support older qb-core functions local info = Core.Functions.GetPlayer(src).PlayerData Player = { firstname = info.charinfo.firstname, lastname = info.charinfo.lastname, name = info.charinfo.firstname.." "..info.charinfo.lastname, cash = info.money["cash"], bank = info.money["bank"], source = info.source, job = info.job.name, jobBoss = info.job.isboss, gang = info.gang.name, gangBoss = info.gang.isboss, onDuty = info.job.onduty, account = info.charinfo.account, citizenId = info.citizenid, } else local info = exports[QBExport]:GetPlayer(src).PlayerData -- this was added to new core then removed? Player = { firstname = info.charinfo.firstname, lastname = info.charinfo.lastname, name = info.charinfo.firstname.." "..info.charinfo.lastname, cash = info.money["cash"], bank = info.money["bank"], source = info.source, job = info.job.name, jobBoss = info.job.isboss, gang = info.gang.name, gangBoss = info.gang.isboss, onDuty = info.job.onduty, account = info.charinfo.account, citizenId = info.citizenid, } end else print("^4ERROR^7: ^2No Core detected for getPlayer() ^7- ^2Check ^3exports^1.^2lua^7") end else if isStarted(ESXExport) and ESX ~= nil then local info = ESX.GetPlayerData() --jsonPrint(info) local cash, bank = 0, 0 for k, v in pairs(ESX.GetPlayerData().accounts) do if v.name == "money" then cash = v.money end if v.name == "bank" then bank = v.money end end Player = { firstname = info.firstName, lastname = info.lastName, source = GetPlayerServerId(PlayerId()), job = info.job.name, --jobBoss = info.job.isboss, --gang = info.gang.name, --gangBoss = info.gang.isboss, onDuty = info.job.onDuty, --account = info.charinfo.account, --citizenId = info.citizenid, name = info.firstName.." "..info.lastName, cash = cash, bank = bank, } elseif isStarted(OXCoreExport) then local info = exports[OXCoreExport]:GetPlayerData() Player = { name = info.firstName.." "..info.lastName, cash = exports[OXInv]:Search('count', "money"), bank = 0, } elseif isStarted(QBXExport) then local info = exports[QBXExport]:GetPlayerData() Player = { firstname = info.charinfo.firstname, lastname = info.charinfo.lastname, name = info.charinfo.firstname.." "..info.charinfo.lastname, cash = info.money["cash"], bank = info.money["bank"], source = info.source, job = info.job.name, jobBoss = info.job.isboss, gang = info.gang.name, gangBoss = info.gang.isboss, onDuty = info.job.onduty, account = info.charinfo.account, citizenId = info.citizenid, } elseif isStarted(QBExport) and not isStarted(QBXExport) then local info = nil Core.Functions.GetPlayerData(function(PlayerData) info = PlayerData end) Player = { firstname = info.charinfo.firstname, lastname = info.charinfo.lastname, name = info.charinfo.firstname.." "..info.charinfo.lastname, cash = info.money["cash"], bank = info.money["bank"], source = info.source, job = info.job.name, jobBoss = info.job.isboss, gang = info.gang.name, gangBoss = info.gang.isboss, onDuty = info.job.onduty, account = info.charinfo.account, citizenId = info.citizenid, } else print("^4ERROR^7: ^2No Core detected for hasJob ^7- ^2Check ^3exports^1.^2lua^7") end end return Player end function GetPlayersFromCoords(coords, radius) local players = {} for _, playerId in ipairs(GetActivePlayers()) do local ped = GetPlayerPed(playerId) if ped and DoesEntityExist(ped) then local playerCoords = GetEntityCoords(ped) if #(coords - playerCoords) <= radius then players[#players+1] = playerId end end end return players end