Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Team Remover [Isn't working?]

Asked by 9 years ago

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
0
Make it table.remove(nobodyt,1) or else the script will remove the first variable so the second variable becomes the first, and then removes the second variable, so the third variable becomes the second, etc. M39a9am3R 3210 — 9y

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

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.


A better solution

All of that said, this script is overly complicated for the task at hand.

A pretty simple specification:

  • Consider every team
  • Find out how many players are on it.
  • If there are no players on it, destroy it.

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
Ad

Answer this question