if Config.Inventory ~= 'codem-inventory' then return end -- ════════════════════════════════════════ -- CODEM-INVENTORY INTEGRATION (ADVANCED) -- ════════════════════════════════════════ 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 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 -- ════════════════════════════════════════ -- INVENTORY FUNCTIONS -- ════════════════════════════════════════ function Inventory.GetAllItems(source) local Player = ValidatePlayer(source) if not Player then return {} end return exports["codem-inventory"]:GetInventory(false, source) 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 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["codem-inventory"]:GetItemByName(source, Inventory.Config.ItemName) if not item then Log('warn', 'Player %s does not have phone item', source) return false end return true end function Inventory.HasPhoneWithNumber(source, phoneNumber) local phones = exports["codem-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 = exports["codem-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["codem-inventory"]:GetInventory(false, 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["codem-inventory"]:SetItemMetadata(source, 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["codem-inventory"]:GetInventory(false, 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["codem-inventory"]:SetItemMetadata(source, 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["codem-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