Hey, I have worked on a Team remover script. Basically, it remove the teams if there is no one on it. It only clear the nobodyt table, but nothing else happen. Anyone have a solution?
local Time = 25 local nobodyt = {} local savelist = {} while true do wait(Time) for i,v in ipairs(game.Players:GetChildren()) do for c,t in ipairs(game.Teams:GetChildren()) do if v.TeamColor == t.TeamColor then for i = 1, #nobodyt do if t.Name == i then table.remove(nobodyt, i) table.insert(savelist, i) end end else if t.Name == "Prisoners" then elseif t.Name == "Immigrants/Civilians" then elseif t.Name == "Visitors" then else table.insert(nobodyt, t.Name) end end end end for e,v in ipairs(nobodyt) do for c,t in ipairs(game.Teams:GetChildren()) do if v == t.Name then for i=1, #savelist do if v == i then print("saved") else print("deny") t:Destroy() end end end end end for i = 1, #nobodyt do table.remove(nobodyt, i) print("table clean1") end for i = 1, #savelist do table.remove(savelist, i) print("table clean2") end end
First, Tab your code correctly.
Next, use meaningful variable names. Why say v
when you mean player
? Also, use _
for a variable you don't use (like the first i
).
I have a number of concerns with this script as it is written.
First, you have a for
loop that goes from 1
to #nobodyt
but can remove elements from nobodyt
. This is very problematic:
-- Consider the following list: list = {2, 3, 5, 7, 11, 13} -- We are going to remove n from this list, wherever n + 1 is divisible by four -- That would be 3, 7, 11 in this list. for i = 1, #list do if (list[i] + 1) % 4 == 0 then table.remove(list, i) end end print( unpack(list) )
What is the result?
attempt to perform arithmetic on field '?' (a nil value)
What's going on here? We can print more to find out by adding this to the beginning and end of the loop:
print("i = ", i, "; list = {", unpack(list) )
We get this as output:
i = 1 ; list = { 2 3 5 7 11 13 i = 1 ; list = { 2 3 5 7 11 13 i = 2 ; list = { 2 3 5 7 11 13 i = 2 ; list = { 2 5 7 11 13 i = 3 ; list = { 2 5 7 11 13 i = 3 ; list = { 2 5 11 13 i = 4 ; list = { 2 5 11 13 i = 4 ; list = { 2 5 11 13 i = 5 ; list = { 2 5 11 13
Notice the problem?
After removing the element at index 2, we go to index 3 -- but that skipped 5 (which is now at index 2).
We can fix this with a while
loop that only increases i
when we don't remove, or we can just go backward:
for i = #list, 1, -1 do if (list[i] + 1) % 4 == 0 then table.remove(list, i) end end
Another problem I see is
if v == i then
i
is a number, and v
is a name. This comparison doesn't make sense. You do it twice.
All of that said, this script is overly complicated for the task at hand.
A pretty simple specification:
This starts with teams as the outer loop, not players, which makes the work very much easier.
for _, team in pairs( game.Teams:GetChildren() ) do local color = team.TeamColor local count = 0 for _, player in pairs( game.Players:GetPlayers() ) do -- The neutral check MAY be superfluous, assuming -- you never put players on neutral. if player.TeamColor == color and not player.Neutral then count = count + 1 end end if count == 0 then team:Destroy() end end
What might be more elegant, because it is useful in many cases for many other purposes, would be to write a function that gets the players on a team:
function getTeam( color ) local team = {}; for _, player in pairs( game.Players:GetPlayers() ) do if player.TeamColor == color and not player.Neutral then table.insert(team, player); end end return team; end for _, team in pairs(game.Teams:GetChildren()) do if #getTeam(team.TeamColor) == 0 then team:Destroy() end end