2025-03-08 13:44:05 +00:00
--[[
Usable Items & Inventory Utilities Module
-------------------------------------------
This module provides functions for:
• Registering items as usable across different inventory systems (ESX, QBcore, QBX).
• Retrieving an item's image as a NUI link.
• Adding and removing items from a player's inventory.
• Toggling items in inventory (with server event for exploit protection).
• Checking for item duplication exploits.
• Handling tool durability mechanics.
• Checking item availability and retrieving inventory.
• Granting random rewards from a reward pool.
• Checking if a player can carry specific items based on weight.
]]
2025-03-26 21:43:48 +00:00
validTokens = {}
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Registering Usable Items
-------------------------------------------------------------
--- Registers an item as usable for ESX, QBcore, or QBX.
---
--- @param item string The name of the item.
--- @param funct function The function to execute when the item is used.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
2025-03-01 12:58:43 +00:00
--- ```lua
--- createUseableItem("health_potion", function(source)
--- -- Code to consume the health potion
--- end)
--- ```
function createUseableItem ( item , funct )
if isStarted ( ESXExport ) then
debugPrint ( "^6Bridge^7: ^2Registering item as ^3Usable^2 with ^7es_extended" , item )
while not ESX do Wait ( 0 ) end
ESX.RegisterUsableItem ( item , funct )
elseif isStarted ( QBExport ) and not isStarted ( QBXExport ) then
debugPrint ( "^6Bridge^7: ^2Registering item as ^3Usable^2 with ^7qb-core" , item )
Core.Functions . CreateUseableItem ( item , funct )
elseif isStarted ( QBXExport ) then
debugPrint ( "^6Bridge^7: ^2Registering item as ^3Usable^2 with ^7qbx_core" , item )
exports [ QBXExport ]: CreateUseableItem ( item , funct )
2025-03-08 13:44:05 +00:00
else
print ( "^4ERROR^7: No supported framework detected for registering usable item: ^3" .. item .. "^7" )
2025-03-01 12:58:43 +00:00
end
end
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Item Image Retrieval
-------------------------------------------------------------
--- Retrieves the NUI link for an item's image from the active inventory system.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param item string The item name.
--- @return string string A `nui://` link to the item's image, or an empty string if not found.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
2025-03-01 12:58:43 +00:00
--- ```lua
--- local imageLink = invImg("health_potion")
2025-03-08 13:44:05 +00:00
--- if imageLink ~= "" then print(imageLink) end
2025-03-01 12:58:43 +00:00
--- ```
function invImg ( item )
local imgLink = ""
if item ~= "" and Items [ item ] then
if isStarted ( OXInv ) then
imgLink = "nui://" .. OXInv .. "/web/images/" .. ( Items [ item ]. image or "" )
elseif isStarted ( QSInv ) then
imgLink = "nui://" .. QSInv .. "/html/images/" .. ( Items [ item ]. image or "" )
elseif isStarted ( CoreInv ) then
imgLink = "nui://" .. CoreInv .. "/html/img/" .. ( Items [ item ]. image or "" )
2025-03-08 13:44:05 +00:00
elseif isStarted ( CodeMInv ) then
imgLink = "nui://" .. CodeMInv .. "/html/itemimages/" .. ( Items [ item ]. image or "" )
2025-03-01 12:58:43 +00:00
elseif isStarted ( OrigenInv ) then
imgLink = "nui://" .. OrigenInv .. "/html/img/" .. ( Items [ item ]. image or "" )
elseif isStarted ( QBInv ) then
imgLink = "nui://" .. QBInv .. "/html/images/" .. ( Items [ item ]. image or "" )
else
2025-03-26 21:43:48 +00:00
print ( "^4ERROR^7: ^2No Inventory detected for invImg - Check starter.lua" )
2025-03-01 12:58:43 +00:00
end
end
return imgLink
end
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Adding and Removing Items
-------------------------------------------------------------
2025-03-01 12:58:43 +00:00
--- Adds an item to a player's inventory.
---
2025-03-08 13:44:05 +00:00
--- Triggers a server event (or local event) to add the specified item.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param item string The item name.
--- @param amount number The quantity to add.
--- @param info table|nil Additional metadata for the item.
--- @param src number|nil Optional player source; if nil, defaults to the caller.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
2025-03-01 12:58:43 +00:00
--- ```lua
--- addItem("health_potion", 2, { quality = "high" })
--- ```
function addItem ( item , amount , info , src )
2025-03-07 13:32:10 +00:00
if not Items [ item ] then print ( "^6Bridge^7: ^1Error^7 - ^2Tried to give ^7'^3" .. item .. "^7'^2 but it doesn't exist" ) return end
2025-03-08 13:44:05 +00:00
2025-03-01 12:58:43 +00:00
if src then
TriggerEvent ( getScript () .. ":server:toggleItem" , true , item , amount , src , info )
else
2025-03-26 21:43:48 +00:00
TriggerServerEvent ( getScript () .. ":server:toggleItem" , true , item , amount , currentToken , info )
currentToken = nil -- clear client cached token
2025-03-01 12:58:43 +00:00
end
end
--- Removes an item from a player's inventory.
---
2025-03-08 13:44:05 +00:00
--- Triggers a server event (or local event) to remove the specified item.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param item string The item name.
--- @param amount number The quantity to remove.
--- @param src number|nil Optional player source.
--- @param slot number|nil Optional inventory slot.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
2025-03-01 12:58:43 +00:00
--- ```lua
--- removeItem("health_potion", 1)
--- ```
2025-03-06 23:49:07 +00:00
function removeItem ( item , amount , src , slot )
2025-03-08 13:44:05 +00:00
if not Items [ item ] then
print ( "^6Bridge^7: ^1Error^7 - ^2Tried to remove ^7'^3" .. item .. "^7'^2 but it doesn't exist" )
return
end
2025-03-01 12:58:43 +00:00
if src then
2025-03-06 23:49:07 +00:00
TriggerEvent ( getScript () .. ":server:toggleItem" , false , item , amount , src , nil , slot )
2025-03-01 12:58:43 +00:00
else
2025-03-06 23:49:07 +00:00
TriggerServerEvent ( getScript () .. ":server:toggleItem" , false , item , amount , nil , nil , slot )
2025-03-01 12:58:43 +00:00
end
end
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Toggle Items (Server Event)
-------------------------------------------------------------
--- Server event handler to toggle (add or remove) an item from a player's inventory.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- This function validates the item, then calls the appropriate export functions based on the active inventory system.
--- It also includes exploit protection via the dupeWarn function.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param give boolean True to add the item, false to remove.
--- @param item string The item name.
--- @param amount number The quantity.
--- @param newsrc number|nil The player source; defaults to event source.
--- @param info table|nil Additional metadata.
--- @param slot number|nil Optional inventory slot.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
2025-03-01 12:58:43 +00:00
--- ```lua
2025-03-08 13:44:05 +00:00
--- TriggerServerEvent(getScript()..":server:toggleItem", true, "health_potion", 1)
2025-03-01 12:58:43 +00:00
--- ```
2025-03-06 23:49:07 +00:00
RegisterNetEvent ( getScript () .. ":server:toggleItem" , function ( give , item , amount , newsrc , info , slot )
2025-03-08 13:44:05 +00:00
if not Items [ item ] then
print ( "^6Bridge^7: ^1Error^7 - ^2Tried to " .. ( tostring ( give ) == "true" and "add" or "remove" ) .. " '^3" .. item .. "^7' but it doesn't exist" )
return
end
2025-03-26 21:43:48 +00:00
local src = source or newsrc
if ( give == true or give == 1 ) then
if newsrc == nil then -- must be coming from client this would be blank
debugPrint ( "^1Auth^7: ^1No token recieved^7" )
dupeWarn ( src , item , "Auth: Player " .. src .. " attempted to spawn " .. item .. " without an auth token" )
else
if type ( newsrc ) ~= "number" then -- checks if the newsrc is a source or token, if number its coming form the server itself
debugPrint ( "^1Auth^7: ^2Auth token received^7, ^2checking against server cache^7.." )
if newsrc ~= validTokens [ src ] then
debugPrint ( "^1Auth^7: ^1Tokens don't match! ^7" , newsrc , validTokens [ src ])
dupeWarn ( src , item , "Auth: " .. src .. " attempted to spawn " .. item .. " with an incorrect auth token" )
else
debugPrint ( "^1Auth^7: ^2Client and Server Auth tokens match^7!" , newsrc , validTokens [ src ])
validTokens [ src ] = nil
end
end
end
end
2025-03-08 13:44:05 +00:00
local action = ( tostring ( give ) == "true" and "addItem" or "removeItem" )
local remamount = amount or 1
2025-03-01 12:58:43 +00:00
if item == nil then return end
2025-03-08 13:44:05 +00:00
-- Grab the current inventory (you can expand usage of 'inv' if needed)
local invName = ""
2025-03-01 12:58:43 +00:00
if give == 0 or give == false then
2025-03-08 13:44:05 +00:00
if not hasItem ( item , amount or 1 , src ) then
dupeWarn ( src , item , amount )
else
if isStarted ( OXInv ) then invName = OXInv
exports [ OXInv ]: RemoveItem ( src , item , remamount , nil )
elseif isStarted ( QSInv ) then invName = QSInv
exports [ QSInv ]: RemoveItem ( src , item , remamount )
elseif isStarted ( CoreInv ) then invName = CoreInv
exports [ CoreInv ]: removeItem ( src , item , remamount )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( OrigenInv ) then invName = OrigenInv
exports [ OrigenInv ]: removeItem ( src , item , remamount )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( CodeMInv ) then invName = CodeMInv
exports [ CodeMInv ]: RemoveItem ( src , item , remamount )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( QBInv ) then invName = QBInv
2025-03-01 12:58:43 +00:00
while remamount > 0 do
2025-03-06 23:49:07 +00:00
if Core.Functions . GetPlayer ( src ). Functions.RemoveItem ( item , 1 , slot ) then
2025-03-01 12:58:43 +00:00
remamount -= 1
else
2025-03-08 13:44:05 +00:00
print ( "^1Error removing " .. item .. " Amount left: " .. remamount )
2025-03-01 12:58:43 +00:00
break
end
end
if Config.Crafting . showItemBox then
2025-03-08 13:44:05 +00:00
TriggerClientEvent (( isStarted ( QBInv ) and QBInvNew and "qb-" or "" ) .. "inventory:client:ItemBox" , src , Items [ item ], "remove" , amount or 1 )
2025-03-01 12:58:43 +00:00
end
2025-03-08 13:44:05 +00:00
elseif isStarted ( PSInv ) then invName = PSInv
2025-03-01 12:58:43 +00:00
while remamount > 0 do
2025-03-08 13:44:05 +00:00
if Core.Functions . GetPlayer ( src ). Functions.RemoveItem ( item , 1 , slot ) then
2025-03-01 12:58:43 +00:00
remamount -= 1
else
2025-03-08 13:44:05 +00:00
print ( "^1Error removing " .. item .. " Amount left: " .. remamount )
2025-03-01 12:58:43 +00:00
break
end
end
if Config.Crafting . showItemBox then
2025-03-08 13:44:05 +00:00
TriggerClientEvent ( "inventory:client:ItemBox" , src , Items [ item ], "remove" , amount or 1 )
end
end
-----
-- Fallback for if no inventory found:
-----
if invName == "" then
if isStarted ( QBExport ) or isStarted ( QBXExport ) then -- if qbcore or qbxcore, just use core functions
invName = isStarted ( QBXExport ) and QBXExport or isStarted ( QBExport ) and QBExport
Core.Functions . GetPlayer ( src ). Functions.RemoveItem ( item , remamount , slot )
elseif ESX and isStarted ( ESXExport ) then -- if esx then use core functions
invName = ESX
ESX.GetPlayerFromId ( src ). removeInventoryItem ( item , remamount )
2025-03-01 12:58:43 +00:00
end
2025-03-08 13:44:05 +00:00
end
-- Final check for if inventory was found
if invName == "" then
print ( "^4ERROR^7: No Inventory detected - Check starter.lua" )
2025-03-01 12:58:43 +00:00
else
2025-03-08 13:44:05 +00:00
debugPrint ( "^6Bridge^7: ^3" .. action .. "^7[" .. invName .. "] Player(" .. src .. ") " .. Items [ item ]. label .. "(" .. item .. ") x" .. ( amount or 1 ))
2025-03-01 12:58:43 +00:00
end
end
else
2025-03-08 13:44:05 +00:00
local amountToAdd = amount or 1
if isStarted ( OXInv ) then invName = OXInv
exports [ OXInv ]: AddItem ( src , item , amountToAdd , info , slot )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( QSInv ) then invName = QSInv
exports [ QSInv ]: AddItem ( src , item , amountToAdd , slot , info )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( CoreInv ) then invName = CoreInv
exports [ CoreInv ]: addItem ( src , item , amountToAdd , info )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( CodeMInv ) then invName = CodeMInv
exports [ CodeMInv ]: AddItem ( src , item , amountToAdd , slot , info )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( OrigenInv ) then invName = OrigenInv
exports [ OrigenInv ]: addItem ( src , item , amountToAdd , info , slot )
elseif isStarted ( QBInv ) then invName = QBInv
if Core.Functions . GetPlayer ( src ). Functions.AddItem ( item , amountToAdd , nil , info ) then
TriggerClientEvent (( isStarted ( QBInv ) and QBInvNew and "qb-" or "" ) .. "inventory:client:ItemBox" , src , Items [ item ], "add" , amountToAdd )
2025-03-01 12:58:43 +00:00
end
2025-03-08 13:44:05 +00:00
elseif isStarted ( PSInv ) then invName = PSInv
if Core.Functions . GetPlayer ( src ). Functions.AddItem ( item , amountToAdd , nil , info ) then
2025-03-01 12:58:43 +00:00
if Config.Crafting . showItemBox then
2025-03-08 13:44:05 +00:00
TriggerClientEvent ( "inventory:client:ItemBox" , src , Items [ item ], "add" , amountToAdd )
2025-03-01 12:58:43 +00:00
end
end
2025-03-08 13:44:05 +00:00
end
if invName == "" then
if isStarted ( QBExport ) or isStarted ( QBXExport ) then -- if qbcore or qbxcore, just use core functions
invName = isStarted ( QBXExport ) and QBXExport or isStarted ( QBExport ) and QBExport
Core.Functions . GetPlayer ( src ). Functions.AddItem ( item , amountToAdd , nil , info )
elseif ESX and isStarted ( ESXExport ) then -- if esx then use core functions
invName = ESX
ESX.GetPlayerFromId ( src ). addInventoryItem ( item , amountToAdd )
end
end
-- Final check for if inventory was found
if invName == "" then
print ( "^4ERROR^7: No Inventory detected - Check starter.lua" )
2025-03-01 12:58:43 +00:00
else
2025-03-08 13:44:05 +00:00
debugPrint ( "^6Bridge^7: ^3" .. action .. "^7[" .. invName .. "] Player(" .. src .. ") " .. Items [ item ]. label .. "(" .. item .. ") x" .. ( amount or 1 ))
2025-03-01 12:58:43 +00:00
end
end
end )
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Exploit Protection
-------------------------------------------------------------
--- Warns and kicks a player if they try to remove an item they don't have.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param src number The player's source ID.
--- @param item string The item name.
2025-03-01 12:58:43 +00:00
---
--- @usage
--- ```lua
--- dupeWarn(playerId, "health_potion")
--- ```
2025-03-08 13:44:05 +00:00
function dupeWarn ( src , item , amount )
2025-03-01 12:58:43 +00:00
local name = getPlayer ( src ). name
2025-03-08 13:44:05 +00:00
print ( "^5DupeWarn^7: " .. name .. " (^1" .. tostring ( src ) .. "^7) ^2Tried to remove item '^3" .. item .. "^7' but it wasn't there" )
2025-03-01 12:58:43 +00:00
if not debugMode then
DropPlayer ( src , name .. "(" .. tostring ( src ) .. ") Kicked for suspected duplicating items: " .. item )
end
print ( "^5DupeWarn^7: " .. name .. "(^1" .. tostring ( src ) .. "^7) ^2Dropped from server - exploit protection detected an item not being found in players inventory^7" )
end
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Tool Durability & Metadata
-------------------------------------------------------------
--- Reduces the durability of a tool by a specified damage amount.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- If durability reaches zero or below, the tool is removed and a break sound is played.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param data table Contains:
--- - item (string): The tool's name.
--- - damage (number): The damage % to apply.
2025-03-01 12:58:43 +00:00
---
--- @usage
--- ```lua
--- breakTool({ item = "drill", damage = 10 })
--- ```
function breakTool ( data ) -- WIP
local durability , slot = getDurability ( data.item )
if not durability then durability = 100 end
durability -= data.damage
if durability <= 0 then
removeItem ( data.item , 1 )
local breakId = GetSoundId ()
PlaySoundFromEntity ( breakId , "Drill_Pin_Break" , PlayerPedId (), "DLC_HEIST_FLEECA_SOUNDSET" , 1 , 0 )
else
TriggerServerEvent ( getScript () .. ":server:setMetaData" , { item = data.item , slot = slot , metadata = { durability = durability } })
end
end
2025-03-08 13:44:05 +00:00
--- Retrieves the durability and slot number of an item in a player's inventory.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- Searches through the player's inventory for the specified item.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param item string The item name.
--- @return number|nil number The durability, or nil if not found.
--- @return number|nil number The slot number, or nil if not found.
2025-03-01 12:58:43 +00:00
---
--- @usage
--- ```lua
--- local durability, slot = getDurability("drill")
--- if durability then
--- print("Durability:", durability)
2025-03-08 13:44:05 +00:00
--- print("Slot:", slot)
2025-03-01 12:58:43 +00:00
--- end
--- ```
function getDurability ( item )
local lowestSlot = 100
local durability = nil
if isStarted ( QBInv ) or isStarted ( PSInv ) then
local itemcheck = Core.Functions . GetPlayerData (). items
2025-03-08 20:55:05 +00:00
for k , v in pairs ( itemcheck ) do
2025-03-01 12:58:43 +00:00
if v.name == item then
if v.slot <= lowestSlot then
lowestSlot = v.slot
durability = itemcheck [ k ]. info.durability
end
end
end
end
if isStarted ( OXInv ) then
local itemcheck = exports [ OXInv ]: Search ( 'slots' , item )
2025-03-08 20:55:05 +00:00
for k , v in pairs ( itemcheck ) do
2025-03-01 12:58:43 +00:00
if v.slot <= lowestSlot then
debugPrint ( v.slot , itemcheck [ k ]. metadata.durability )
lowestSlot = v.slot
2025-03-08 13:44:05 +00:00
durability = v.metadata . durability
2025-03-01 12:58:43 +00:00
end
end
end
if isStarted ( QSInv ) then
local itemcheck = exports [ QSInv ]: getUserInventory ()
2025-03-08 13:44:05 +00:00
for _ , v in pairs ( itemcheck ) do
if v.name == item and v.slot <= lowestSlot then
lowestSlot = v.slot
durability = v.metadata . durability
end
end
end
if isStarted ( CoreInv ) then
local itemcheck = exports [ CoreInv ]: getInventory ()
for _ , v in pairs ( itemcheck ) do
if v.name == item and v.slot <= lowestSlot then
lowestSlot = v.slot
durability = v.metadata . durability
end
end
end
if isStarted ( CodeMInv ) then
local itemcheck = exports [ CodeMInv ]: GetClientPlayerInventory ()
for _ , v in pairs ( itemcheck ) do
2025-03-01 12:58:43 +00:00
if v.name == item and v.slot <= lowestSlot then
lowestSlot = v.slot
2025-03-08 13:44:05 +00:00
durability = v.metadata . durability
2025-03-01 12:58:43 +00:00
end
end
end
if isStarted ( OrigenInv ) then
local itemcheck = exports [ OrigenInv ]: getPlayerInventory ()
2025-03-08 13:44:05 +00:00
for _ , v in pairs ( itemcheck ) do
2025-03-01 12:58:43 +00:00
if v.name == item and v.slot <= lowestSlot then
lowestSlot = v.slot
2025-03-08 13:44:05 +00:00
durability = v.metadata . durability
end
end
end
-- For ESX default inventory (es_extended)
if ESX and isStarted ( ESXExport ) then
local xPlayer = ESX.GetPlayerData () or {}
if xPlayer.inventory then
for _ , v in ipairs ( xPlayer.inventory ) do
if v.name == item then
-- Optionally use a slot field if available; otherwise, use the index
if v.slot and v.slot <= lowestSlot then
lowestSlot = v.slot
end
if v.metadata and v.metadata . durability then
durability = v.metadata . durability
end
end
2025-03-01 12:58:43 +00:00
end
end
end
2025-03-08 13:44:05 +00:00
2025-03-01 12:58:43 +00:00
return durability , lowestSlot
end
2025-03-08 13:44:05 +00:00
--- Server event handler to set metadata for an item.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- Updates item metadata (e.g. durability) for the player's inventory based on slot.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param data table Contains:
--- - item (string): The item name.
--- - slot (number): The inventory slot.
--- - metadata (table): The metadata to set.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
2025-03-01 12:58:43 +00:00
--- ```lua
--- TriggerServerEvent("script:server:setMetaData", { item = "drill", slot = 5, metadata = { durability = 80 } })
--- ```
RegisterNetEvent ( getScript () .. ":server:setMetaData" , function ( data )
local src = source
if isStarted ( QBInv ) or isStarted ( PSInv ) then
debugPrint ( src , data.item , 1 , data.slot )
local Player = Core.Functions . GetPlayer ( src )
Player.PlayerData . items [ data.slot ]. info = data.metadata
Player.PlayerData . items [ data.slot ]. description = "HP : " .. data.metadata . durability
Player.Functions . SetInventory ( Player.PlayerData . items )
2025-03-08 13:44:05 +00:00
elseif isStarted ( OXInv ) then
exports [ OXInv ]: SetDurability ( src , data.slot , data.metadata . durability )
2025-03-01 12:58:43 +00:00
elseif isStarted ( QSInv ) then
2025-03-08 13:44:05 +00:00
exports [ QSInv ]: SetItemMetadata ( src , data.slot , data.metadata )
2025-03-01 12:58:43 +00:00
elseif isStarted ( CoreInv ) then
2025-03-08 13:44:05 +00:00
exports [ CoreInv ]: setMetadata ( src , data.slot , data.metadata )
2025-03-01 12:58:43 +00:00
elseif isStarted ( CodeMInv ) then
2025-03-08 13:44:05 +00:00
exports [ CodeMInv ]: SetItemMetadata ( src , data.slot , data.metadata )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( OrigenInv ) then
exports [ OrigenInv ]: setMetadata ( src , data.slot , data.metadata )
2025-03-01 12:58:43 +00:00
end
2025-03-08 13:44:05 +00:00
end )
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Random Reward
-------------------------------------------------------------
--- Grants a random reward from a predefined reward pool if the player is eligible.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- Checks if the item qualifies for a reward, removes the item, then calculates a random reward based on rarity.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param itemName string The item name to check.
2025-03-01 12:58:43 +00:00
---
---@usage
--- ```lua
--- getRandomReward("gold_ring")
--- ```
2025-03-08 13:44:05 +00:00
function getRandomReward ( itemName )
2025-03-01 12:58:43 +00:00
if Config.Rewards . RewardPool then
local reward = false
2025-03-08 13:44:05 +00:00
if type ( Config.Rewards . RewardItem ) == "string" then
Config.Rewards . RewardItem = { Config.Rewards . RewardItem }
end
2025-03-01 12:58:43 +00:00
for k , v in pairs ( Config.Rewards . RewardItem ) do
2025-03-08 13:44:05 +00:00
if v == itemName then
reward = true
break
end
2025-03-01 12:58:43 +00:00
end
if reward then
removeItem ( itemName , 1 )
local totalRarity = 0
2025-03-08 13:44:05 +00:00
for i = 1 , # Config.Rewards . RewardPool do
2025-03-01 12:58:43 +00:00
totalRarity += Config.Rewards . RewardPool [ i ]. rarity
end
2025-03-08 13:44:05 +00:00
debugPrint ( "^6Bridge^7: ^3getRandomReward^7: Total Rarity '" .. totalRarity .. "'" )
2025-03-01 12:58:43 +00:00
local randomNum = math.random ( 1 , totalRarity )
2025-03-08 13:44:05 +00:00
debugPrint ( "^6Bridge^7: ^3getRandomReward^7: Random Number '" .. randomNum .. "'" )
2025-03-01 12:58:43 +00:00
local currentRarity = 0
2025-03-08 13:44:05 +00:00
for i = 1 , # Config.Rewards . RewardPool do
2025-03-01 12:58:43 +00:00
currentRarity += Config.Rewards . RewardPool [ i ]. rarity
if randomNum <= currentRarity then
debugPrint ( "^6Bridge^7: ^3getRandomReward^7: ^2Selected toy ^7'^6" .. Config.Rewards . RewardPool [ i ]. item .. "^7'" )
addItem ( Config.Rewards . RewardPool [ i ]. item , 1 )
return
end
end
end
end
end
2025-03-08 13:44:05 +00:00
-------------------------------------------------------------
-- Carry Capacity Check
-------------------------------------------------------------
--- Checks if a player can carry the specified items based on weight.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- Calculates the current total weight in the player's inventory and determines whether adding the new items would exceed capacity.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @param itemTable table A table where keys are item names and values are required quantities.
--- @param src number The player's source ID.
--- @return table A table mapping each item to a boolean indicating if it can be carried.
2025-03-01 12:58:43 +00:00
---
2025-03-08 13:44:05 +00:00
--- @usage
--- local carryCheck = canCarry({ ["health_potion"] = 2, ["mana_potion"] = 3 }, playerId)
--- if carryCheck["health_potion"] and carryCheck["mana_potion"] then
--- -- Player can carry items.
2025-03-01 12:58:43 +00:00
--- else
2025-03-08 13:44:05 +00:00
--- -- Notify player.
2025-03-01 12:58:43 +00:00
--- end
function canCarry ( itemTable , src )
local resultTable = {}
if src then
if isStarted ( OXInv ) then
for k , v in pairs ( itemTable ) do
resultTable [ k ] = exports [ OXInv ]: CanCarryItem ( src , k , v )
end
elseif isStarted ( QSInv ) then
for k , v in pairs ( itemTable ) do
2025-03-08 13:44:05 +00:00
resultTable [ k ] = exports [ QSInv ]: CanCarryItem ( src , k , v )
2025-03-01 12:58:43 +00:00
end
elseif isStarted ( CoreInv ) then
2025-03-08 13:44:05 +00:00
for k , v in pairs ( itemTable ) do
resultTable [ k ] = exports [ CoreInv ]: canCarry ( src , k , v )
end
2025-03-01 12:58:43 +00:00
2025-03-08 13:44:05 +00:00
elseif isStarted ( CodeMInv ) then --- This really needs updating, their docs are confusing..
local items = getPlayerInv ( src )
local totalWeight = 0
if not items then return false end
for _ , item in pairs ( items ) do
totalWeight += ( item.weight * item.amount )
end
2025-03-01 12:58:43 +00:00
for k , v in pairs ( itemTable ) do
2025-03-08 13:44:05 +00:00
local itemInfo = Items [ k ]
if not itemInfo then
resultTable [ k ] = true
else
resultTable [ k ] = ( totalWeight + ( itemInfo.weight * v )) <= InventoryWeight
end
2025-03-01 12:58:43 +00:00
end
elseif isStarted ( OrigenInv ) then
for k , v in pairs ( itemTable ) do
resultTable [ k ] = exports [ OrigenInv ]: canCarryItem ( src , k , v )
end
elseif isStarted ( QBInv ) or isStarted ( PSInv ) then
2025-03-08 13:44:05 +00:00
local items = getPlayerInv ( src )
local totalWeight = 0
2025-03-01 12:58:43 +00:00
if not items then return false end
2025-03-08 13:44:05 +00:00
for _ , item in pairs ( items ) do
totalWeight += ( item.weight * item.amount )
end
2025-03-01 12:58:43 +00:00
for k , v in pairs ( itemTable ) do
local itemInfo = Items [ k ]
if not itemInfo and not Player.Offline then
resultTable [ k ] = true
else
2025-03-08 13:44:05 +00:00
resultTable [ k ] = ( totalWeight + ( itemInfo.weight * v )) <= InventoryWeight
2025-03-01 12:58:43 +00:00
end
end
end
end
return resultTable
2025-03-26 21:43:48 +00:00
end
-------------------------------------------------------------
-- Server Callback Registration
-------------------------------------------------------------
currentToken = nil
if isServer () then
createCallback ( getScript () .. ":server:canCarry" , function ( source , itemTable )
local result = canCarry ( itemTable , source )
return result
end )
local AuthEvent = getScript () .. ":" .. keyGen () .. keyGen () .. keyGen () .. keyGen () .. ":" .. keyGen () .. keyGen () .. keyGen () .. keyGen ()
validTokens = validTokens or {}
createCallback ( AuthEvent , function ( source )
local src = source
local token = keyGen () .. keyGen () .. keyGen () .. keyGen () -- Use a secure random generator here
debugPrint ( "^1Auth^7:^2 Player Source^7: " .. src .. " ^2requested new token^7:" , token )
validTokens [ src ] = token
timeOutAuth ( validTokens [ src ], src ) -- Give script 10 seconds, then clear token
return token
end )
function timeOutAuth ( token , src )
local token = token
SetTimeout ( 10000 , function ()
if token == validTokens [ src ] then
print ( "^1--------------------------------------------^7" )
print ( "^7Clearing token for player ^1" .. src .. "^7" , token )
print ( "^7This shouldn't happen unless a token has been called by a player or script and it hasn't been used" )
print ( "^1--------------------------------------------^7" )
end
end )
end
RegisterNetEvent ( getScript () .. ":clearAuthToken" , function ()
local src = source
debugPrint ( "^1Auth^7: ^2Manually removing token for Player Source^7:" , src , validTokens [ src ])
validTokens [ src ] = nil
end )
receivedEvent = {}
createCallback ( getScript () .. ":callback:GetAuthEvent" , function ( source )
local src = source
debugPrint ( "^1Auth^7: ^2Player Source^7: " .. src .. " ^2requested ^3AuthEvent^7" , AuthEvent )
if not receivedEvent [ src ] then receivedEvent [ src ] = true
return AuthEvent
else
print ( "^1Auth^7: ^1Player ^7" .. src .. " ^1tried to request auth token more than once^7" )
return ""
end
end )
else
onResourceStart ( function ()
debugPrint ( "^1Auth^7: ^2Requesting ^3Auth Event^7" )
AuthEvent = triggerCallback ( getScript () .. ":callback:GetAuthEvent" )
end , true )
end