How do I stop this from constantly giving the player (x) item?

I need my system to give the player their new weapon every time they hit the requirement for the next weapon.

The system works fine, besides for one thing. The weapon is CONSTANTLY given to the player when they already had the weapon.

I have already tried adding a Folder inside ReplicatedStorage that puts the index of the weapon they had inside of it, and then check if the player has that value and if they don’t then it will give them the weapon (basically, it should stop the player from getting the weapon that they already have)
After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

Here is the code where the issue is (this is NOT all of the code in that script, just the part you would need to understand what’s going on):

playersWeapons = Instance.new("Folder", rep)
playersWeapons.Name = "HasBlades"

local function doesPlayerAlreadyHaveThatSword(plr, i)
	local value = false
	
	if playersWeapons:FindFirstChild(plr.Name) then
		for _, v in ipairs(rep.HasBlades[plr.Name]:GetChildren()) do
			if v.Name == i then
				value = true
				print("User already has sword")
			end
		end
	end
	return value
end

local function gaveSword(plr, i)
	if not playersWeapons:FindFirstChild(plr.Name) then
		local new = Instance.new("Folder",playersWeapons)
		new.Name = plr.Name
		local newBlade = Instance.new("IntValue",new)
		newBlade.Name = i
	elseif playersWeapons:FindFirstChild(plr.Name) and not rep.HasBlades[plr.Name]:FindFirstChild(i) then
		local newBlade = Instance.new("IntValue",rep.HasBlades[plr.Name])
		newBlade.Name = i
	end
end

local function giveSword(plr)
	repeat wait() until workspace:FindFirstChild(plr.Name)
		-- give them the actual blade
		local weaponInfo = mod.Weapons
			for i, weapon in pairs(weaponInfo) do
				local hasSword = doesPlayerAlreadyHaveThatSword(plr, i)
				if hasSword == false then
					if plr.leaderstats.Power.Value >= weapon["Unlock At"] and weapon["Unlockable"] == true then
						for _, v in ipairs(plr.Backpack:GetChildren()) do
							v:Destroy()
						end
						for _, v in ipairs(plr.Character:GetChildren()) do
								if v:IsA("Tool") then
									v:Destroy()
								end
						end
						local new = weapon["Blade Path"]:Clone()
						new.Parent = plr.Character
						gaveSword(plr, i)
					end
				end
			end
end

players.PlayerAdded:Connect(function(plr)
	repeat wait() until plr:FindFirstChild("leaderstats")	
	while true do wait(1)
		giveSword(plr)
	end
			
end)

I feel like I have made a stupid mistake that has messed up the whole script, but I’m not sure.

There’s 2 things that I see, one of them being a probably cause for the issue.

The main issue I see that could be doing that is

while true do wait(1)
	giveSword(plr)
end

This code gives the player a sword every second, why did you do it like this? Were you trying to make it work after the player respawns? You can do this instead

giveSword(plr)
plr.CharacterAdded:Connect(function()
	giveSword(plr)
end)

(I made the code run when the player is added as well for the first time the player joins, just incase)

The second unrelated thing is that you should never use the 2nd parameter of Instance.new(), it’s slow

1 Like

Why are you constantly calling the function inside a while loop in the player added connection?

Why not just use characterAdded instead. That should solve it giving multiple times.

Just do what @EmbatTheHybrid said.

1 Like

If I used .CharacterAdded then it wouldn’t update the weapon when the player gets the requirement.

What do you mean by what you said?

Does this do the correct thing?

local Players = game:GetService("Players")

local weaponInfo = mod.Weapons

local charAddConns = {}
local currentWeapons = {}


local function giveWeapon(plr, weaponName)
	plr.Backpack:ClearAllChildren()
	local char = plr.Character
	if not char then
		return
	end
	local equippedWeapon = char:FindFirstChildOfClass("Tool")
	if equippedWeapon then
		equippedWeapon:Destroy()
	end
	local weaponModel = weaponInfo[weaponName].BladePath:Clone()
	weaponModel.Parent = plr.Character
end

local function onPowerChanged(plr, newPower)
	local requiredPower, weaponName = -1, nil
	for weaponName, info in pairs(weaponInfo) do
		if not info.Unlockable then
			continue
		end
		local unlockAt = info.UnlockAt
		if unlockAt <= newPower and unlockAt > requiredPower then
			requiredPower, weaponName = unlockAt, weaponName
		end
	end
	if weaponName ~= currentWeapons[plr] then
		currentWeapons[plr] = weaponName
		giveWeapon(plr, weaponName)
	end
end

local function onCharacterAdded(char)
	local plr = Players:GetPlayerFromCharacter(char)
	giveWeapon(plr, currentWeapons[plr])
end

local function onPlayerAdded(plr)
	local leaderStats = plr:WaitForChild("leaderstats")
	leaderstats.Power.Changed:Connect(function(newPower)
		onPowerChanged(plr, newPower)
	end)

	-- this is called once here so that the name of the first weapon that the player should get
	-- is set as set as the value of currentWeapons[plr]
	onPowerChanged(plr)

	charAddConns[plr] = plr.CharacterAdded:Connect(onCharacterAdded)
	if plr.Character then
		giveWeapon(plr, currentWeapons[plr]
	end
end

local function onPlayerRemoving(plr)
	currentWeapons[plr] = nil
	charAddConns[plr]:Disconnect()
	charAddConns[plr] = nil
end

Players.PlayerAdded:Connect(onPlayerAdded)
Players.PlayerRemoved:Connect(onPlayerRemoving)