How do i make a magnitude script that targets the strongest, weakest in range

As @BandQueenForever said, loop through all the Folder with all of the other Folders inside by using :GetDescendants() which will allow you to get every single content inside of the Folder. Then inside the loop, you would make few if statements by checking if there is a Health value inside. I am not sure what kind of logic you want to approach for checking the weakest and strongest Humanoid, but the simplest one would be to just check if Health Value is 100, then that is the strongest Humanoid.

Once you find a Strongest Humanoid, you can use a Magnitude Value between your Character and the NPC. Check if Magnitude Value is below a specified number and then do something.

but how though? operators just don’t work, they just keep choosing randomly.

Which operators are you talking about?

like >=,=<,==,

Operators should be fine, it’s definitely the logic you are approaching that is not being precise.

well, if zombies get in range of the tower, i can’t just like make if below 15 then shoot. no it will shoot randomly, you can’t sort it somehow.

Can you show us the most recently updated code for your Zombie Script?

table.sort() exists precisely for this, unless I am missing out on something major.

while wait(0.3) do
	
		local towertorso = script.Parent.Torso
		local mobs = workspace.Enemies
		local humanoid = script.Parent.Humanoid
		local humanoidnpc = script.Parent.Humanoid
		--local humanim = humanoidnpc:LoadAnimation(script.Parent.fire)
		local function FindFirstTarget()
			local maxDistance = 150
			local nearestTarget = nil

			for i, target in ipairs(mobs:GetChildren()) do
				local distance = (target.HumanoidRootPart.Position - towertorso.Position).Magnitude
				if target.DistanceToWaypoint.Value < 999 and target.MovingValue.Value > 0 then

					towertorso.Parent:SetPrimaryPartCFrame(CFrame.new(towertorso.Parent.PrimaryPart.Position,target.Torso.Position))
					maxDistance = distance
				end
			end

		end

		while true do
			local target = FindFirstTarget()
			local FireSound = Instance.new('Sound')
			local damagenumber = 3
			if target then
				
				
			
	
				-- Do something
			end
				


			task.wait(0.5)
		end


	end

Why do you have a while loop nested inside another while loop?

how do you even sort strong health and weak health throughout a magnitude script that checks a ‘‘Zombies’’ folder?

doesn’t matter the First while loop is domiant.

You can try using table.insert() to insert the specified Humanoid to be shot at. After that you can just loop through the new table of the Specified Humanoids.

Assuming you already have a table of humanoids, you can loop through them and keep setting variables to find which one has the least/most value (then return it). I’d do this:

function SortHumanoids(Humanoids,Mode) -- Mode is either "Least" or "Most"
	local selected = nil
	local healthThreshold

	if Mode == "Least" then
		HealthThreshold = math.huge
		for i,v in pairs(Humanoids) do
			if v.Health < HealthThreshold then
				HealthThreshold = v.Health
				selected = v
			end
		end
	elseif Mode == "Most" then
		HealthThreshold = -math.huge
		for i,v in pairs(Humanoids) do
			if v.Health > HealthThreshold then
				HealthThreshold = v.Health
				selected = v
			end
		end
	end
	return selected
end

Would that work on a loop if a zombie is very close to the tower? or something?

That depends on your logic, all this function does is take an array of humanoids (e.g. {Humanoid, Humanoid, Humanoid}) and gives you which one has the most/least health.

alr ill try my own logic then.

Hey uhh… does humanoids must have :GetDescendants?

You have to get all zombies in the range, and sort its health accordingly to your logic. It shouldn’t be that hard I think.

Something like this perhaps?
Don’t open if you’d like to try making this system by yourself.

Result of my attempt.
local range = 750
local in_range = {} --table for zombies that are in the range.
--cutting off zombies that aren't in range
for i,v in pairs(zombies_folder:GetChildren()) do --assuming they're all zombie models and nothing else.
	if v.PrimaryPart.Position.Magnitude <= range then 
		--don't forget to assign a PrimaryPart to them, 
		--or just refer to any part of zombie you want to compare the range with.
		table.insert(in_range,v)
	end
end

--sorting zombies that are in range by health
table.sort(in_range,function(a,b) 
	return a.Humanoid.Health > b.Humanoid.Health --if this were "<" it would sort from lowest to highest.
end) --sort "in_range" and return the sorted result

print(in_range) --this is sorted. it should print from highest to lowest health.
--to find highest, use in_range[1]. 
--to find lowest, use in_range[#in_range]
--to randomize, use in_range[math.random(1,#in_range)]

Using a dummy table I’ve made and this modified version of it.

Modified Version
local zombies_table = {
	{
		Position = 0;
		Health = 0;
	};
	{
		Position = 1000;
		Health = 10;
	};
	{
		Position = 750;
		Health = 99;
	};
	{
		Position = 100;
		Health = 1;
	};
	{
		Position = 777;
		Health = 7;
	};
}

local range = 750
local in_range = {}
for i,v in pairs(zombies_table) do
	if v.Position <= range then
		table.insert(in_range,v)
	end
end

table.sort(in_range,function(a,b) 
	return a.Health > b.Health
end)

print(in_range)

I was able to get this result out of it:
image
(Note that ones that aren’t in the range are cut off. Also you cannot sort the range and health at the same time since it would cancel each other out.)

I hope this helps you even just a little.

I’m not exactly sure what you mean by this. You can FIND them with get descendants (and you could put that in the function I provided, but you’d have to add if v:IsA("Humanoid"). However, @hallowynl’s solution works pretty well as long as you have a folder for NPCs, so you might want to go with theirs.

1 Like