Tables not working as expected?

Greetings - I’ve been working and experimenting with different methods of Melee based attacks.
Yes I’m aware of the module, I’m still attempting to create my own method.

My issue is as shown below:
I’m trying to get it so that only 1 of the Humanoids are input into the Table as opposed to all 45 that it collides with.

I understand that I can fix this by using break in my pairs, however, I’m looking to damage multiple NPCs rather than the single one when the requirements are met.

Below is a brief example of what I’m attempting to achieve.
As you can see, because of the multiple additions into the tables, the Humanoids gain the 15 Dmg * whatever the parts found were as opposed to my intended - Simple just -15 dmg.

local Part = script.Parent
local _H = {}

local Multi

Multi = game:GetService("RunService").Heartbeat:Connect(function()
	_H = {}
	local _i = Part:GetTouchingParts()
	for _,i in pairs (_i) do
		if i.Parent:FindFirstChild("Humanoid") ~= nil then
			for _,p in pairs (_H) do
				if p == i.Parent["Humanoid"] then
					print("Found")
				else
					table.insert(_H, i.Parent["Humanoid"])
				end
			end
		end
	end
	Damage()
end)

Damage = function()
	for _,i in pairs (_H) do
		if i:IsA("Humanoid") then
			i:TakeDamage(15)
			Multi:Disconnect()
		end
	end
end

You’ll need to add a sort of some kind to check if the humanoid already exist in the table,
also I don’t suggest running a loop every 1/40th of a second if you can get around it. It’s a little overkill, especially considering normal humans only process 24-48 frames a second as motion.

2 Likes

you can use table.find to search for values in an array, with this you can check if they exist within the H table, also you might want to clean the H table afterwards because tables referencing roblox instances will not be gc’d.

1 Like

Why not instead of making a list of humanoids to damage, make a hashmap of humanoids. Set to true if they are to be damaged.

Multi = game:GetService("RunService").Heartbeat:Connect(function()
	_H = {}
	local _i = Part:GetTouchingParts()
	for _,i in pairs (_i) do
		if i.Parent:FindFirstChild("Humanoid") ~= nil then
			for p, _ in pairs (_H) do
				if p == i.Parent["Humanoid"] then
					print("Found")
				else
					_H[i.Parent.Humanoid] = true
				end
			end
		end
	end
	Damage()
end)

Then for damage, you can just flip the key and value identifiers like so:

Damage = function()
	for i, _ in pairs (_H) do
		if i:IsA("Humanoid") then
			i:TakeDamage(15)
			Multi:Disconnect()
		end
	end
end

Now, if I attempt to repeatedly set the same value true, it’ll remain true. It will not flood the table with the same humanoids as the humanoids are the keys, not the value. Also, take Mentsuu and Crowdsource tips as well if you want a full fix.

Extra

Have more descriptive variables names, it helps a lot in parsing through the code and reasoning about it. This is because “BodyParts” has more meaning than “_i”. It’ll not only help other people read your code, but it’ll also help you in the future when you reread it.

1 Like

Using an example above I was able to create a working function for this: HOWEVER.

local Part = script.Parent
local _H = {}

local Multi

Multi = game:GetService("RunService").Heartbeat:Connect(function()
	local _i = Part:GetTouchingParts()
	for _,i in pairs (_i) do
		if i.Parent:FindFirstChild("Humanoid") ~= nil then
			local E = table.find(_H, i.Parent["Humanoid"])
			if E then
			else
				table.insert(_H, i.Parent["Humanoid"])
			end
		end
	end
	Damage()
end)

Damage = function()
	for _,i in pairs (_H) do
		if i:IsA("Humanoid") then
			i:TakeDamage(15)
			Multi:Disconnect()
		end
	end
	_H = {}
end

When implemented into my Sword, it still restricts to a single Humanoid?

Strike = function()
   Debounce = true
   local anim = Player.Character:WaitForChild("Humanoid"):LoadAnimation(script.anim)
   anim:Play()

   _D = game:GetService("RunService").Heartbeat:Connect(function()
   	local _i = Tool["Hitbox"]:GetTouchingParts()
   	for _,i in pairs (_i) do
   		if i.Parent:FindFirstChild("Humanoid") ~= nil then
   			local E = table.find(_H, i.Parent["Humanoid"])
   			if E then
   			else
   				table.insert(_H, i.Parent["Humanoid"])
   			end
   		end
   	end
   	Damage()
   end)
   
   repeat wait(.75) until anim.IsPlaying == false
   Debounce = false
   _D:Disconnect()
end

Damage = function()
   for _,i in pairs (_H) do
   	if i:IsA("Humanoid") then
   		i:TakeDamage(15)
   		_D:Disconnect()
   	end
   end
   _H = {}
end

Can anyone help with this?

Uh, do you still have the problem you mentioned now or is it solved?