Hello!
I have got a tool saving script. But it doesn’t recheck if a tool has been removed from the player’s backpack and their character. And what I want it to do is update the tools table and remove that tool that has been removed from the player.
Script:
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local player_data = DataStoreService:GetDataStore("TestData4")
local RemoveSoldItem = ReplicatedStorage.Remotes.RemoveSoldItem
local LostItem = ReplicatedStorage.Remotes.LostItem
local tools = {} -- Stores both backpack & equipped tools
local CharacterReferences = {}
-- Function to save a player's inventory safely
local function SaveInventory(client)
if not client then return end -- Safety check
local key = "client_" .. client.UserId
local Backpack = client:FindFirstChild("Backpack") or Instance.new("Backpack", client)
local Character = client.Character
tools[client] = {BackpackTools = {}, EquippedTools = {}}
-- ✅ Save tools from Character (equipped tools)
if Character then
for _, item in ipairs(Character:GetChildren()) do
if item:IsA("Tool") then
table.insert(tools[client].EquippedTools, item.Name)
end
end
end
-- ✅ Save tools from Backpack
for _, item in ipairs(Backpack:GetChildren()) do
if item:IsA("Tool") then
table.insert(tools[client].BackpackTools, item.Name)
end
end
-- ✅ Safe data saving using UpdateAsync
local success, err = pcall(function()
player_data:UpdateAsync(key, function(oldData)
return tools[client]
end)
end)
if success then
print("💾 Saved Inventory for " .. client.Name .. ": Equipped[" .. table.concat(tools[client].EquippedTools, ", ") .. "] Backpack[" .. table.concat(tools[client].BackpackTools, ", ") .. "]")
else
warn("❌ Failed to save inventory for " .. client.Name .. ": " .. err)
end
end
-- Function to load a player's inventory
local function LoadInventory(client)
local key = "client_" .. client.UserId
local inventory = player_data:GetAsync(key) or {BackpackTools = {}, EquippedTools = {}}
tools[client] = inventory
print("📦 Loaded Inventory for " .. client.Name .. ": Equipped[" .. table.concat(inventory.EquippedTools, ", ") .. "] Backpack[" .. table.concat(inventory.BackpackTools, ", ") .. "]")
local Backpack = client:FindFirstChild("Backpack") or Instance.new("Backpack", client)
-- Clear existing tools before loading
for _, item in ipairs(Backpack:GetChildren()) do
if item:IsA("Tool") then
item:Destroy()
end
end
local Character = client.Character
if Character then
for _, item in ipairs(Character:GetChildren()) do
if item:IsA("Tool") then
item:Destroy()
end
end
end
-- ✅ Load Backpack tools
for _, name in ipairs(inventory.BackpackTools) do
local tool = ReplicatedStorage.ItemAssets:FindFirstChild(name) or ReplicatedStorage.LureAssets:FindFirstChild(name)
if tool then
local ClonedTool = tool:Clone()
ClonedTool.Parent = Backpack
print("✔ Added tool to backpack:", name)
else
warn("⚠ Item could not be cloned:", name)
end
end
-- ✅ Load Equipped tools into Character
if Character then
for _, name in ipairs(inventory.EquippedTools) do
local tool = ReplicatedStorage.ItemAssets:FindFirstChild(name) or ReplicatedStorage.LureAssets:FindFirstChild(name)
if tool then
local ClonedTool = tool:Clone()
ClonedTool.Parent = Character
print("✔ Equipped tool:", name)
else
warn("⚠ Item could not be cloned:", name)
end
end
end
end
-- Handles when a player joins
Players.PlayerAdded:Connect(function(client)
client.CharacterAdded:Wait()
local char = client.Character
CharacterReferences[client.UserId] = char
LoadInventory(client) -- Load inventory on join
end)
-- Handles when a player leaves
Players.PlayerRemoving:Connect(function(client)
-- ✅ Move equipped tools back to the backpack before saving
local char = CharacterReferences[client.UserId]
if char then
print("Character found before player leaves:", char:GetChildren())
for _, item in ipairs(char:GetChildren()) do
if item:IsA("Tool") then
local itemClone = item:Clone()
itemClone.Parent = client.Backpack
item:Destroy()
print("Moved " .. item.Name .. " to the player's backpack!")
end
end
else
print("❌ No character found for", client.Name)
end
-- ✅ Update tools table with current backpack tools
local Backpack = client:FindFirstChild("Backpack")
if Backpack then
tools[client] = {BackpackTools = {}, EquippedTools = {}}
for _, item in ipairs(Backpack:GetChildren()) do
if item:IsA("Tool") then
table.insert(tools[client].BackpackTools, item.Name)
end
end
end
-- ✅ Save inventory after moving tools
SaveInventory(client)
-- ✅ Cleanup
CharacterReferences[client.UserId] = nil
tools[client] = nil
end)
-- Handles item removal when sold
RemoveSoldItem.OnServerEvent:Connect(function(plr, toolItemName)
if tools[plr] then
-- Remove from Backpack list
local TargetPosition = table.find(tools[plr].BackpackTools, toolItemName)
if TargetPosition then
table.remove(tools[plr].BackpackTools, TargetPosition)
end
-- Remove from Equipped list
TargetPosition = table.find(tools[plr].EquippedTools, toolItemName)
if TargetPosition then
table.remove(tools[plr].EquippedTools, TargetPosition)
end
-- ✅ Remove tool from player's Backpack or Character
local Backpack = plr:FindFirstChild("Backpack")
local Character = plr.Character
if Backpack then
local tool = Backpack:FindFirstChild(toolItemName)
if tool then tool:Destroy() end
end
if Character then
local tool = Character:FindFirstChild(toolItemName)
if tool then tool:Destroy() end
end
-- ✅ Immediately save updated inventory
SaveInventory(plr)
end
end)
-- Handles lost items
LostItem.OnServerEvent:Connect(function(plr, ItemName)
if tools[plr] then
-- Remove from Backpack list
local TargetPosition = table.find(tools[plr].BackpackTools, ItemName)
if TargetPosition then
table.remove(tools[plr].BackpackTools, TargetPosition)
end
-- Remove from Equipped list
TargetPosition = table.find(tools[plr].EquippedTools, ItemName)
if TargetPosition then
table.remove(tools[plr].EquippedTools, TargetPosition)
end
-- ✅ Remove tool from player's Backpack or Character
local Backpack = plr:FindFirstChild("Backpack")
local Character = plr.Character
if Backpack then
local tool = Backpack:FindFirstChild(ItemName)
if tool then tool:Destroy() end
end
if Character then
local tool = Character:FindFirstChild(ItemName)
if tool then tool:Destroy() end
end
-- ✅ Immediately save updated inventory
SaveInventory(plr)
end
end)
All help is appreciated!