Multiple instances of beam weapon increases damage

I have this beam weapon system that I modified from a template (which I’ve unfortunately lost). It consists of a beam, a local script, and a server script.

Local script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local FireLaser = ReplicatedStorage:WaitForChild("FireXenonEvent")

local tool = script.Parent
local player = game:GetService("Players").LocalPlayer
local blastEffect = tool:WaitForChild("BlastEffect")
local origin = tool:WaitForChild("OriginPart")
local sound = origin:WaitForChild("Fire")
local firing = false

-- You can change the three numbers here.
local duration = 0.3 -- How long (in seconds) the beam is visible.
local cooldown = 1 -- How long (in seconds) you can wait between shots (If this is shorter than duration, you can fire multiple beams at once!)
local damage = 15 -- How much damage the beam does when it hits a player. 100 is the full HP of a standard Robloxian.

local visuals = {} -- If you can build and script confidently, you can place beams, particle effects, and anything else with an "Enabled" property in here, and it will activate/deactivate during "Duration". If you place anything that has no "Enabled" property in this array, it will break the script.

tool.Equipped:connect(function(mouse)
 	mouse.Button1Down:connect(function()
		if firing == false then 
			local ray = Ray.new(tool.Handle.CFrame.p, (mouse.Hit.p - tool.Handle.CFrame.p).unit * 300)
			local part, position = workspace:FindPartOnRay(ray, player.Character, false, true)
			firing = true
			FireLaser:FireServer(duration, cooldown, damage, visuals, part, position, blastEffect, origin, sound)
			wait(cooldown)
			firing = false			
		end
	end)
end)

Server script:

local ReplicatedStorage = game:GetService("ReplicatedStorage")
if not ReplicatedStorage:FindFirstChild("FireXenonEvent") then
	FireLaser = Instance.new("RemoteEvent", ReplicatedStorage)
	FireLaser.Name = "FireXenonEvent"
else
	FireLaser = ReplicatedStorage:FindFirstChild("FireXenonEvent")
end
local tool = script.Parent

function fireBeamVisuals(visuals, duration)
	for i, effect in ipairs(visuals) do
		effect.Enabled = true
	end
	wait(duration)
	for i, effect in ipairs(visuals) do
		effect.Enabled = false
	end
end

function createTarget(visuals, blastEffect, origin)
	local targetPart = Instance.new("Part", workspace)
	targetPart.Transparency = 1
	targetPart.Anchored = true
	targetPart.Locked = true
	targetPart.CanCollide = false
	local targetPoint = Instance.new ("Attachment", targetPart)
	local beam = blastEffect:clone()
	beam.Parent = workspace
	beam.Attachment0 = origin.Origin
	beam.Attachment1 = targetPoint
	visuals[#visuals + 1] = beam
	return targetPart, beam, visuals
end

local function beamEffect(target, damage)
	target:TakeDamage(damage)
end

local function onLaserFired(player, duration, cooldown, damage, visuals, part, position, blastEffect, origin, sound, targetPart)
	local target, beam, visuals = createTarget(visuals, blastEffect, origin)
	target.Position = position
	if part then
		local humanoid = part.Parent:FindFirstChild("Humanoid")
		if not humanoid then
			humanoid = part.Parent.Parent:FindFirstChild("Humanoid")
		end
		if humanoid then
			local oldHealth = humanoid.Health
			humanoid.Health = oldHealth - damage
		end
	end
	sound:play()
	fireBeamVisuals(visuals, duration)
	target:Destroy()
	beam:Destroy()
	targetPart:Destroy()
end
 
FireLaser.OnServerEvent:Connect(onLaserFired)

Everything works well aside from one thing: when I fire the beam and there’s another player with the same tool, the damage increases by the number of players wielding the tool. If the tool’s damage was set to, say, 50, and there were 3 players in the game with the same tool, then whenever I used the tool, it would deal 150 damage.

3 Likes

First of all, you shouldn’t entrust the client with sending you the damage, cooldown and other data which define a tools behaviour. These should be only calculated from the server preferably using a Config module.