2026-04-14 17:41:39 +02:00

268 lines
8.8 KiB
Lua

if Config.Inventory ~= 'tgiann-inventory' then return end
-- ════════════════════════════════════════
-- TGIANN-INVENTORY INTEGRATION
---@source https://docs.tgiann.com/scripts/tgiann-inventory/exports/server
-- ════════════════════════════════════════
local Inventory = {}
Inventory.Config = {
ItemName = Config.ItemName or 'phone',
RequireItem = Config.ItemRequired ~= false,
DebugMode = Config.Debug or false
}
-- ════════════════════════════════════════
-- UTILITY FUNCTIONS
-- ════════════════════════════════════════
local function Log(type, message, ...)
if not Inventory.Config.DebugMode then return end
local prefix = '^2[Inventory]^7'
if type == 'error' then prefix = '^1[Inventory ERROR]^7' end
if type == 'warn' then prefix = '^3[Inventory WARNING]^7' end
print(string.format('%s %s', prefix, string.format(message, ...)))
end
-- ════════════════════════════════════════
-- INVENTORY FUNCTIONS
-- ════════════════════════════════════════
function Inventory.GetAllItems(source)
return exports["tgiann-inventory"]:GetPlayerItems(source) or {}
end
function Inventory.GetItemsByName(source, itemName)
itemName = itemName or Inventory.Config.ItemName
local items = {}
local inventory = Inventory.GetAllItems(source)
for slot, item in pairs(inventory) do
if item and item.name == itemName then
items[#items + 1] = {
slot = slot,
name = item.name,
amount = item.amount or 1,
info = item.info or {},
CodemPhoneNumber = item.info?.CodemPhoneNumber,
CodemFormattedNumber = item.info?.CodemFormattedNumber
}
end
end
-- Log('debug', 'Found %d item(s) for player %s', #items, source)
return items
end
local function ValidatePlayer(source)
local src = tonumber(source)
if not src or src == 0 then
Log('error', 'Invalid source: %s', tostring(source))
return nil
end
local Player = Core.Functions.GetPlayer(src)
if not Player then
Log('error', 'Player not found for source: %s', src)
return nil
end
return Player
end
function Inventory.GetPhoneItem(source)
if not Inventory.Config.RequireItem then
Log('debug', 'Item requirement disabled, returning true')
return true
end
local Player = ValidatePlayer(source)
if not Player then return false end
local item = exports["tgiann-inventory"]:GetItemByName(source, Inventory.Config.ItemName)
if not item or item.amount == 0 then
Log('warn', 'Player %s does not have phone item', source)
return nil
end
return true
end
function Inventory.HasPhoneWithNumber(source, phoneNumber)
local phones = Inventory.GetItemsByName(source, Inventory.Config.ItemName)
if #phones == 0 then
Log('debug', 'Player %s has no phone items', source)
return {
success = false,
itemAmount = 0,
}
end
local foundPhoneWithDifferentNumber = false
local differentNumber = nil
for i = 1, #phones do
local phone = phones[i]
if phone.info.CodemPhoneNumber then
if phone.info.CodemPhoneNumber == phoneNumber then
Log('debug', 'Player %s has phone with number %s', source, phoneNumber)
return {
success = true,
myPhone = true
}
else
foundPhoneWithDifferentNumber = true
differentNumber = phone.info.CodemPhoneNumber or nil
end
end
end
if foundPhoneWithDifferentNumber then
Log('debug', 'Player %s has phone but with different number: %s (expected: %s)', source, differentNumber,
phoneNumber)
return {
success = true,
myPhone = false,
differentNumber = differentNumber
}
end
Log('debug', 'Player %s has phone but no number assigned', source)
return {
success = true,
myPhone = false,
firstSetup = true
}
end
function Inventory.HasAnyPhone(source)
local phones = Inventory.GetItemsByName(source, Inventory.Config.ItemName)
if #phones == 0 then
Log('debug', 'Player %s has no phone items', source)
return false
end
Log('debug', 'Player %s has %d phone item(s)', source, #phones)
return true
end
function Inventory.SetPhoneNumber(source, phoneNumber)
if not phoneNumber then
Log('error', 'SetPhoneNumber called without phone number')
return false
end
local items = exports["tgiann-inventory"]:GetPlayerItems(source)
local updated = false
for slot, item in pairs(items) do
if item and item.name == Inventory.Config.ItemName then
if item.info?.CodemPhoneNumber then
Log('debug', 'Skipping phone in slot %s (already has number)', slot)
goto continue
end
item.info = item.info or {}
item.info.CodemPhoneNumber = phoneNumber
item.info.CodemFormattedNumber = FormatPhoneNumber(phoneNumber)
Log('debug', 'Assigned number %s to phone in slot %s', phoneNumber, slot)
updated = true
exports["tgiann-inventory"]:SetItemData(source, item.name, item.slot, item.info)
Log('debug', 'Phone number successfully set for player %s', source)
break
end
::continue::
end
if not updated then
Log('warn', 'Could not find available phone to assign number for player %s', source)
end
return updated
end
function Inventory.UpdatePhoneMetadata(source, phoneNumber, metadata)
local items = exports["tgiann-inventory"]:GetPlayerItems(source)
local updated = false
for slot, item in pairs(items) do
if item and item.name == Inventory.Config.ItemName and item.info?.CodemPhoneNumber == phoneNumber then
item.info = item.info or {}
for key, value in pairs(metadata) do
if value == "DELETE" or value == nil then
item.info[key] = nil
else
item.info[key] = value
end
end
exports["tgiann-inventory"]:SetItemData(source, item.name, item.slot, item.info)
Log('debug', 'Updated metadata for phone %s in slot %s', phoneNumber, slot)
updated = true
break
end
end
return updated
end
function Inventory.RemoveInventoryItem(source, itemname, amount)
local Player = ValidatePlayer(source)
if not Player then return false end
local removed = exports["tgiann-inventory"]:RemoveItem(source, itemname, amount)
if removed then
Log('debug', 'Removed %d of item %s from player %s', amount, itemname, source)
else
Log('warn', 'Failed to remove item %s from player %s', itemname, source)
end
return removed
end
Citizen.CreateThread(function()
while Core == nil or not Core.Functions.CreateUseableItem do
Citizen.Wait(100)
end
Core.Functions.CreateUseableItem(Inventory.Config.ItemName, function(source, item)
if item then
TriggerClientEvent("codem-phone:PhoneUsed", source, item)
end
end)
if Config.BatterySystem.enable then
Core.Functions.CreateUseableItem(Config.BatterySystem.powerBankItemName, function(source, item)
TriggerClientEvent("codem-phone:UsePowerBank", source)
Inventory.RemoveInventoryItem(source, Config.BatterySystem.powerBankItemName, 1)
end)
end
end)
RPC.Register('codem-phone:inventory:HasPhoneItem', function(source, phoneNumber)
return Inventory.HasPhoneWithNumber(source, phoneNumber)
end)
RPC.Register('codem-phone:inventory:HasAnyPhone', function(source)
return Inventory.HasAnyPhone(source)
end)
RPC.Register('codem-phone:inventory:GetPhoneItem', function(source)
return Inventory.GetPhoneItem(source)
end)
GetPlayerInventoryItem = Inventory.GetPhoneItem
SetPhoneNumber = Inventory.SetPhoneNumber
UpdatePhoneMetadata = Inventory.UpdatePhoneMetadata
GetItemsByName = Inventory.GetItemsByName