Question about Events / cloning a tool to a backpack OnServerEvent for a lot of weapons

I have a problem that I can’t seem to solve on my own regarding events.
When for example I make a GUI that gives a tool to a player, 3 different tools
for each GUI figure (3 text boxes for example, each for getting a separate tool )

sample code in GUI TextBox :

   script.Parent.MouseButton1Click:Connect(function()
    local event = replicatedstorage.event
    event:FireServer()

sample script in server script service for the event :

game.ReplicatedStorage.event.OnServerEvent:Connect(function(plr) 
 local tool1 =  game.replicatedstorage.tool1 
tool1.Parent = plr.Backpack

So that would mean I would have to create 100 events for 100 weapons, and i’ve got way more weapons than that , so any suggestions on what I could do instead of using hundred of events? (also would I have to use a separate script in each of the hundred weapon purchase gui buttons rather than one central script or something?)
Thanks for any help.

1 Like

You only ever need a maximum of one remote, just pass certain info in as a parameter depending on what you want to do.

--Client
Event:FireServer("Tool1") -- or whatever tool you are sending or wanting

-- Server
Event.OnServerEvent:Connect(function(Player, ToolName)
	if ToolName == "Tool1" then -- Check a string like this
	
	elseif ToolName == "Tool2" then -- Check another string like this

	elseif ServerStorage:FindFirstChild(ToolName) then -- What if the tool is in a service? Check like this

	end
end)

You can pass as many parameters as you want, in this case the parameter is ToolName and that variable will change depending on what you send to the server. In your case you could do what i said above and simply pass the tool name in as a parameter and then grab the tool wherever you have them stored using the tool name that you received.

but how would the server know what (ToolName) is ?
The tools are parented to the backpack and player,toolname would be nil (right?)
and how would I implement that,
can I do it this way, like when a player purchases a tool a value is updated to the ToolName , so if I define a variable in the event like : ToolName = player.folder.ToolNameValue.Value
and then if that string value is for example “tool1” then if toolname = “tool1” it will retrun the specific tool for that player . And through this way would I need to add a
separate

local tool1   =  repstorage.tool1:Clone()
 tool1.Parent = player.backpack

local tool2 = etc etc.
for each tool then? or is there a simpler solution

When you :FireServer(ToolName) you include the tool name there. You can do it in a number of ways.
One way you could do it is simply naming the buttons the same as the tool name. Then when you click the button just pass the name of the button on your GUI into the remote so the server can get it.


-- Client
for _, Button in pairs(Buttons:GetChildren()) do -- This part depends how you have your UI setup but this is what i would personally do.
	Button.MouseButton1Click:Connect(function()
		Event:FireServer(Button.Name)
	end)
end

-- Server
Event.OnServerEvent:Connect(function(Player, ToolName)
	if type(ToolName) ~= "string" then
		return
	end
	
	if ServerStorage:FindFirstChild(ToolName) then
		ServerStorage[ToolName]:Clone().Parent = Player.Backpack
	end
end)

There is a lot more efficient ways to handle things like this but this is the gist of how you could handle numerous items with minimal code and events.

1 Like

I understand now that you can send data while firing an event that way, but for some reason that code isn’t working

Certain things need to be declared in that such as the Event variable. It’s not meant to work just like that, it was more-less and example as to how you could accomplish this. Add prints to your code to see what is running and what is being sent. Any outputs would be helpful as well.

image

onserverevent :

local Event = game.ReplicatedStorage.Event
Event.OnServerEvent:Connect(function(Player, ToolName)
	if type(ToolName) ~= "string" then
		print("type")
		return
	end
	
	if game.ServerStorage:FindFirstChild(ToolName) then
		print("not cloned yet")
		game.ServerStorage[ToolName]:Clone().Parent = Player.Backpack
		print("cloned")
	end
end)

script parented to buttons :

local buttons = script.Parent
local event = game.ReplicatedStorage.Event
for _, Button in pairs(buttons:GetChildren()) do

	Button.MouseButton1Click:Connect(function()
		event:FireServer(Button.Name)
		print("fired")
	end)
end

output :
image

image

I guess can only be fired from client can be fixed by putting that in a local script but what about mousebuttin1click isnt a valid member,?

Well you can only fire the SERVER from the CLIENT. MouseButton1Click is an event that can be fired from any GUI button. The script i sent should work if you have a frame will of buttons. You’ll want to handle all of that with a local script and then :FireServer(), then have the OnServerEvent be handled by a server script.

So in your case the Button variable that you get from that for loop should be a TextButton or an ImageButton and the buttons variable should be a frame that holds all of your buttons. The problem you are having is that the script is inside of the frame as well so the script is going to look for MouseButton1Click inside of that script which will error as it doesn’t exist.

for _, Button in pairs(buttons:GetChildren()) do
        if Button:IsA("TextButton") then -- or whatever class the button is.
	Button.MouseButton1Click:Connect(function()
		event:FireServer(Button.Name)
		print("fired")
	end)
       end
end

ignore my indenting, typing this in the box thing

1 Like