Hats are cloned in the ‘Hats’ folder through a serverscript in serverscriptservice but LocalScript handles purchasing.
local Manage = RS.RemoteEvents:WaitForChild("ManageClones",math.huge)
local cloneCurrentHatRemote = RS.RemoteEvents:WaitForChild("CloneCurrentHat")
Manage.OnServerEvent:Connect(function(plr,obj,parent)
local objC = obj:Clone()
if objC.ClassName == "Accessory" then
local things = parent:GetChildren()
for i,v in pairs(things) do
if v.ClassName == "Accessory" then
v:Destroy()
objC.Parent = parent
end
end
else
local objC = obj:Clone()
objC.Parent = parent
end
end)
cloneCurrentHatRemote.OnServerEvent:connect(function(player, hat, parent)
local character = workspace:WaitForChild(player.Name)
local things = character:GetChildren()
for i,v in pairs(things) do
if v.ClassName == "Accessory" then
v:Destroy()
end
end
hat:clone().Parent = character
end)
I thought of that situation too, but it doesn’t sound to be like that, since it prints “Got hat keys” whenever it adds something to the dictionary that goes into the datastore
I asked whether it prints, and in post 11, I was answered positively
Should cloneCurrentHatRemote also copy the hat into the players Hats folder or is the done by the ManageClones event? One thing in the ManageClones is it will only clone an Accessory correctly if there are already accessories in the parent.
if objC.ClassName == "Accessory" then
local things = parent:GetChildren()
for i,v in pairs(things) do
if v.ClassName == "Accessory" then
v:Destroy()
objC.Parent = parent
end
end
--- Should objC.Parent = parent by here instead?
I think in cloneCurrentHatRemote you should do:
local hats = player:WaitForChild("Hats")
if hats:FindFirstChild(hat.Name) == nil then
hat:Clone().Parent = hats
end
if objC.ClassName == "Accessory" then
local things = parent:GetChildren()
for i,v in pairs(things) do
if v.ClassName == "Accessory" then
v:Destroy()
objC.Parent = parent
end
end
Because every player spawns with the starter hat, I have to remove it when a player decides to equip a hat they have bought. This is a part from the LocalScript which handles purchasing:
elseif purchase.Text == "EQUIP" then
local chosenHat = hat.Parent:FindFirstChild(hat.Value)
local currentHats = currentHatFolder:GetChildren()
for i,v in pairs(currentHats) do
v:Destroy()
end
chosenHat:clone().Parent = currentHatFolder
purchase.Text = "UNEQUIP"
purchase.BackgroundColor3 = Color3.fromRGB(255, 178, 24)
manageRemote:FireServer(chosenHat, player.Character)
There is an ‘else’ statement just incase if the player isn’t trying to buy a hat, the weapon they are trying to buy is placed straight into startergear/backpack.
else
local objC = obj:Clone()
objC.Parent = parent
end
I changed the system so that hats are cloned through the server. However, they still aren’t saving.
function LoadData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local hats = plr:WaitForChild("Hats");
for i, v in next, vault:GetAsync(uid) do
print("Loading: ", i, " = ", v)
local tool = RS:FindFirstChild(v)
if tool then
tool:Clone().Parent = pack
tool:Clone().Parent = gear
end
local hat = RS.HatShop.ShopItem:FindFirstChild(v)
if hat then
hat:Clone().Parent = hats
print("Loaded hats")
end
end
end
I added a print(“Loaded hats”) but it doesn’t print.
Looks like none of them are hats so I presume there is still an issue with adding the hats to the hats folder. Can you show us your update code for that?
purchase.MouseButton1Down:connect(function()
local hat = shopItem:FindFirstChild(currentItem)
if not hatFolder:FindFirstChild(hat.Value) then
if purchase.Text == "PURCHASE" then
local cost = hat:WaitForChild("Cost")
local leaderstats = player:WaitForChild("leaderstats")
local points = leaderstats:WaitForChild("Points")
local takeMoneyRemote = game.ReplicatedStorage.RemoteEvents:WaitForChild("TakeMoney",math.huge)
if points.Value > cost.Value then
local chosenHat = hat.Parent:FindFirstChild(hat.Value)
cloneHatRemote:FireServer(chosenHat) -- Called here.
purchase.BackgroundColor3 = Color3.fromRGB(143, 143, 143)
purchase.Text = "EQUIP"
takeMoneyRemote:FireServer(points.Value, cost.Value)
end
This is the localscript in a gui that handles purchases.
What you are doing should be fine. I would recommend testing this in Start Server in Roblox studio. You should see if the hats are getting added to the Hats folder under the Player. You should also add prints to the SaveData function to see what is going on there.
function SaveData(plr, uid)
local pack = plr:WaitForChild("Backpack");
local gear = plr:WaitForChild("StarterGear");
local keys = {};
if #gear:GetChildren() > 0 then
for i, v in next, gear:GetChildren() do
keys[GenerateID(20)] = v.Name;
end;
end;
local hats = plr:WaitForChild("Hats")
local hatsKeys = {}
if #hats:GetChildren() > 0 then
print("More than 0 hats")
for x, y in next, hats:GetChildren() do
hatsKeys[GenerateID(20)] = y.Name;
print("ID Generated for "..y.Name)
print(hatsKeys)
print("Got hat keys")
end
end
vault:SetAsync(uid, keys, hatsKeys);
end;
This is the problem. You are trying to use SetAsync with two values when it only takes one. I would recommend just putting the hats into the same keys table as you were earlier.