1 RemoteEvent 12 Tools

My tools use a special system to down any person under a certain health and if they’re downed through a boolvalue check, it works, but I wanna make so only one script handles the execution and not 7 tools, as firing one remote event can cause stress because if the player would fire 7 events.
My ideas were a table function with tool names that have custom functions, for example, fire event if the player executed with tool Fire Sword but any other tools that are not Fire Sword should not do the function.
Another problem is animation loading, how do I load an animation only once and not load it twice? but re-load when player respawns.
Here is my initial script:

local CollectionSevrice = game:GetService("CollectionService")
function BurnPlayers(Player)
	for _,v in game:GetService("Players"):GetPlayers() do
		if v.Name ~= Player.Name then
			if (v.Character.HumanoidRootPart.Position - Player.Character.HumanoidRootPart.Position).Magnitude <= 15 then
				v:SetAttribute("Burn", 15)
			end
		end
	end 
end
local SpecialFunctions = {
	["Fire Sword"] = function(Player)
		BurnPlayers(Player)
	end,
	["Ice Sword"] = function(...)
		print(...)
	end,
}
Execution.OnServerEvent:Connect(function(Player:Player?, Tool:Tool?)
	local Character = Player.Character
	local Tool = Character:FindFirstChild(tostring(Tool))
	local RaycastHitbox = require(game:GetService("ReplicatedStorage"):WaitForChild("Modules"):WaitForChild("RaycastHitboxV4"))
	if Character:FindFirstChild("Downed").Value == false and Character:FindFirstChild("Ragdolled").Value == false and Character:FindFirstChildOfClass("Humanoid").Health > 0 then -- Sanity checks, prevents player from firing in case they're not suppose to.
		local Animator = Character:FindFirstChildOfClass("Humanoid"):FindFirstChildOfClass("Animator")
		local Animation = Animator:LoadAnimation(ServerStorage.Core.Animations:FindFirstChild(Tool)) -- Fetch animation then play it.
		for _,v in game:GetService("Players"):GetPlayers() do
			if v.UserId ~= Player.UserId then
			local Victim = v.Character
				local Humanoid = Victim:FindFirstChildOfClass("Humanoid")
				local Params = RaycastParams.new()
				Params.FilterDescendantsInstances = {Character}
				Params.FilterType = Enum.RaycastFilterType.Exclude
				local Hitbox = RaycastHitbox.new(Handle)
				Hitbox.RaycastParams = Params
				Hitbox.OnHit:Connect(function(hit, humanoid:Humanoid?)
					if humanoid.Health > 0 then
						if table.find(SpecialFunctions, Tool.Name) then
							SpecialFunctions[Tool.Name](Player)
						end
						humanoid:TakeDamage(35)
						Tool.Handle.Execute:Play()
						require(ServerScriptService.Modules.Handler):GiveObjectValue(humanoid, Player)
					end
				end)
				if Victim:FindFirstChild("Downed").Value == true then
					if Victim:FindFirstChild("Ragdolled").Value == true then
						if Humanoid.Health > 0 then
							if (Character.HumanoidRootPart.Position - Victim.HumanoidRootPart.Position).Magnitude <= 8 then
								if not CollectionSevrice:HasTag(Player, "Cooldown") then
									CollectionSevrice:AddTag(Player, "Cooldown")
									task.delay(3,function()
										CollectionSevrice:RemoveTag(Player, "Cooldown")
									end)
									Animation:Play()
									Tool.Handle.Stomp:Play()
									Hitbox:HitStart()
									task.wait(Animation.Length - 0.2)
									Hitbox:HitStop()
								end
							end
						end
					end
				end
			end
		end
	end
end)

How the event is fired is pretty straight forward too.

UserInputService.InputBegan:Connect(function(Input, t)
	if t then return end
	if Input.KeyCode == Enum.KeyCode.E then
		local Tool = game:GetService("Players").LocalPlayer.Character:FindFirstChildOfClass("Tool")
		Execution:FireServer(Tool)
	end
end)
1 Like

Well I did some clean-ups and it now works perfectly. Bug-Free too.