How do I make this script only activate when a player clicks while holding a weapon

Because server scripts can’t do player:GetMouse() so I had to use a local script and remote event

I think you can use tool.Activated event and tool.Deactivated event to get the same result

Have you tried using Tool.Activated (roblox.com) and Tool.Deactivated (roblox.com)? These work in a server script afaik, and fire when the left mouse button’s held and released.

But then the player will not be able to hold down the mouse

you could use a variable for that and a while loop

maybe something like:

tool.Deactivated:Connect(function()
mouseButtonDown = false
end)

tool.Activated:Connect(function()
mouseButtonDown = true

while mouseButtonDown do
	wait(0.25)
	
end

end)

And I really don’t think the problem is with the local script because it works fine

The problem is still not fixed

If we removed the local script and the remote event (could try this by cloning your current tool and remove it’s local script and remote event) and test it out

local tool = script.Parent

local mouseButtonDown = false
local hasTouched = false


tool.Deactivated:Connect(function()
		mouseButtonDown = false
end)

tool.Activated:Connect(function()
		mouseButtonDown = true
end)

script.Parent.Handle.Touched:Connect(function(otherCollider)
	if hasTouched == false and mouseButtonDown == true then
		hasTouched = true
	
		local humanoid = otherCollider.Parent:FindFirstChildOfClass("Humanoid")
	
		if humanoid then
			humanoid:TakeDamage(25)
		end
		
		wait(0.45)
		hasTouched = false
	end
end)

Yes that’s what I did but it did not fix the main issue

The main issue was that it damaged the player even if they didn’t held the mouse button down right?

Yes that is the main issue and it is also the only issue

Just disconnect the touched event.when you are done with it.

Alternatively you can wait for a touched event instead of conmecting to it but that would probably bring more problems.

local TouchedConnection = Part.Touched:Connect(function(otherPart)
    print(otherPart, "touched me!")
end)
task.wait(10)
TouchedConnection:Disconnect()-- After 10 secs part will not listen for touches anymore

Simply disconnect your event after the animation finishes or after a certain amount of time.

The issue is that the script damages other players even when the player with the tool did not click and I already tried disconnecting the function

Yes, so disconnect it when you have finished with it and it should not listen for touched events anymore.

I tested that but the script would do nothing

Does nothing? Are you sure you are using it correctly?
insert this script into a part

local Connection = script.Parent.Touched:Connect(function(otherPart)
    print(otherPart,"touched me!")
end)
task.wait(5)
Connection:Disconnect()

Walk over it then after 5 secconds it will stop printing.

Also, to note, try refraining from connecting signals inside signals as you can end up with lag and incorrect multiplied inputs. Especially if you are not disconnecting them.

I inserted the script inside the handle but it did not change anything

Place a brick inside of the workspace and put the script inside of that. This isn’t a solution I am trying to get you to learn for yourself how to disconnect so you can solve it yourself.

out of curiousity, so if left a signal within a signal without disconnecting them, they would stack up basically? Will the stack itself cause the most lag or upon being triggered? maybe both?

Exactly. Some people tend to forget that part. Its actually pretty easy to see it yourself in action. I actually had a problem like that in a game I made where I would Connect to the character loding then connect for character appearance loaded.

over time I found the server became unplayable.

local Mouse = Player:GetMouse()
--Bad
Mouse.Button1Down:Connect(function()
    print("Press")
    Mouse.Button1Up:Connect(function()
        print("Release")
    end)
end)
-- Good
Mouse.Button1Down:Connect(function()
    print("Press")
end)
Mouse.Button1Up:Connect(function()
    print("Release")
end)
-- Or even better
Mouse.Button1Down:Connect(function()
    print("Press")
    Mouse.Button1Up:Wait()
    print("Release")
end)