Help with defining player in a server script

I have items that when activated, they give the person iron(cash), but it doesn’t work because they are on the ground, not in the players backpack, so I don’t know how I can define the player.

Here is the script:

local Players = game:GetService("Players")
local Exist = false
	script.Parent.Activated:Connect(function()
		if not Exist then
			Exist = true	
			player.leaderstats.Iron.Value = player.leaderstats.Iron.Value+50
			script.Parent:Destroy()
			Exist = false
	end
end)

This script is inside a local script inside of a tool?

it is a server script inside a tool inside of workspace

Hmmm, instead of that, I have another solution for you. First, set up a remove event inside of replicated storage. Call it whatever you want, I’ll keep it as “IncreaseIron” just for the sake of simplicity. Instead of a server script, inside the tool, make a local script and put this code inside it:

local event = game.ReplicatedStorage.IncreaseIron -- Change to your event name
script.Parent.Activated:Connect(function()
	print("Activated") -- Just for testing purposes
	event:FireServer()
        script.Parent:Destroy()
end)

Now, In the server script service, make a script like this:

local event = game.ReplicatedStorage.IncreaseIron

event.OnServerEvent:Connect(function(plr)
        plr.leaderstats.Iron.Value = plr.leaderstats.Iron.Value + 50
end)

This works because, in local scripts you can’t change the value because of filtering enabled. Through the remote event, it sends a signal to the server with an automatic value of the player who sent it, and using that value, it changes their Iron value.

IMPORTANT: Make sure the script inside the tool is a local script and the one in the server script service is a normal script.

I will have over 30+ different tools on the ground that will respawn. I don’t want to have 30 different scripts in server script service. Is there any other way?

Oh no, there is a VERY simple way to do this. You can do this with one event and one script in the server script service even with one hundred tools using this technique:
The current script in the “Iron” tool looks like this:

local event = game.ReplicatedStorage.IncreaseIron -- Change to your event name
script.Parent.Activated:Connect(function()
	print("Activated") -- Just for testing purposes
	event:FireServer()
        script.Parent:Destroy()
end)

All you have to do is inside of this line event:FireServer(), just change it to this, event:FireServer("Iron50"). What this did was, it fired the event, plus gave a value that says that this tool fired the “Iron50” event. To make this work change the script in server script service to this:

local event = game.ReplicatedStorage.IncreaseIron

event.OnServerEvent:Connect(function(plr, type) -- This now takes in that "Iron50" string as the variable, type.
        if type == "Iron50" then
                plr.leaderstats.Iron.Value = plr.leaderstats.Iron.Value + 50
        end
end)

Now, using this knowledge, for each differnt tool, make a unique “type”, such as Iron60, and fire server with that value given, and to read it, just make an elseif inside the script with something like, elseif type == "YourTYPE" and you can do it infinitely many times

1 Like
local Tool = script.Parent
local Debounce = false
local WaitTimeBetweenSlashes = 2 -- seconds
Tool.Activated:Connect(function()
       if not Debounce then
              Debounce = true
              local Character = Tool.Parent.Parent
              local Player = game.Players:GetPlayerFromCharacter(Character)
              if Player then
                     Player.leaderstats.Iron.Value += 50
              end
              wait(WaitTimeBetweenSlashes)
              Debounce = false
       end
end)

I can’t believe you guys are working up complicated answers with remotes when a simple GetPlayerFromCharacter can be advised. (Server script btw)

3 Likes

It doesn’t give iron. For whatever reason, my iron stays the same when I use it. It might be a misspell. It was a server script inside the tool not the actual handle.

I figured out the reason why. The tool is in workspace, and the character variable is

local Character = Tool.Parent.Parent

which can’t work because the parent of the parent of the tool is the game.

No, my mistake. tool.Parent is the character when u equip it.

1 Like

It works now thank you, my game and my future games are saved.

Why not define Player and Character outside the event? The tool will always have the same player and character as long as tools aren’t droppable (in which case it should be defined inside the equipped event rather than activated).

Further simplified:

local Tool = script.Parent

local Player = Tool.Parent.Parent
local Character = Player.Character or Player.CharacterAdded:Wait()

local Slashing = false
local SlashInterval = 2

Tool.Activated:Connect(function()
	if Slashing then
		return
	end
	
	Player.leaderstats.Iron.Value += 50
	
	Slashing = true
	wait(SlashInterval)
	Slashing = false
end)

I don’t see any use for that which makes it better. (Also your if slashing then return, an if not statement is fine)