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

Putting all players in a table?

Asked by 10 years ago
        randomplr = {}
        for _,v in pairs (game.Players:GetChildren()) do
            table.insert(randomplr, v.Name)
            chosenplayerone = game.Players:FindFirstChild(randomplr[1])
            chosenplayertwo = game.Players:FindFirstChild(randomplr[2])
            chosenplayerone.Status.Value = "Vigilante"
            chosenplayertwo.Status.Value = "Hero"
        end

I'm having a problem on output explaining a problem with "Argument 1 = nil", this is confusing me as I have been through many different methods and none work. It is running with two people, so that's not the problem. I have been blinded!

3 answers

Log in to vote
3
Answered by
MrNicNac 855 Moderation Voter
10 years ago

You don't need a for loop to get the players. Using :GetPlayers() already returns a table of players. You just need to make a function to select two random players - making sure the same one isn't selected twice.

NOTE : I did not input a fail-safe checking if there are at least two players.

local Players = Game.Players:GetPlayers()

function GetTwoRandomPlayers()
    local Chosen = {}
    local first = Players[math.random(1, #Players)];
    table.insert(Chosen, first)
    local second ;
    repeat
        second = Players[math.random(1, #Players)];
    until second ~= Chosen[1];
    table.insert(Chosen, second);
    return Chosen[1], Chosen[2]
end

local Player1, Player2 = GetTwoRandomPlayers();
Player1.Status.Value = "Vigilante";
Player2.Status.Value = "Hero";

0
I get the same error on line 5, near random, it says 'bad argument #2 to 'random', interval is empty. AstralKick 25 — 10y
Ad
Log in to vote
0
Answered by 10 years ago
randomplr = {}
for _,v in pairs (game.Players:GetChildren()) do
    table.insert(randomplr, v.Name)
end
    chosenplayerone = game.Players:FindFirstChild(randomplr[1])
    chosenplayertwo = game.Players:FindFirstChild(randomplr[2])
    chosenplayerone.Status.Value = "Vigilante"
    chosenplayertwo.Status.Value = "Hero"
0
I've already got something defining the amount of players, so that isn't a fix. Thanks anyway. :-) AstralKick 25 — 10y
0
i've edited my answer. TheGuyWithAShortName 673 — 10y
Log in to vote
0
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
10 years ago

You should select the players after going through the entire list, so your code referring to chosenplayerone and chosenplayertwo should happen after the for loop ends.

There's two things to keep in mind then. The first is that if you don't have at least two players in the game at this time, your script will error.

Second, the order won't be random! While the order may be in some strange order, every time the script is run (in a relatively close amount of time, i.e., within a few minutes) the order should be the same, so the same two people will be chosen over and over.

You have to either shuffle the list or pick random positions (picking random positions is much easier).

The modifications would look like this:

players = {}
for _,v in pairs (game.Players:GetChildren()) do
        table.insert(players, v.Name)
end
chosenplayerone = game.Players:FindFirstChild( players[math.random(1,#players)] );
repeat
    chosenplayertwo = game.Players:FindFirstChild( players[math.random(1,#players)] );
until chosenplayertwo ~= chosenplayerone
chosenplayerone.Status.Value = "Vigilante"
chosenplayertwo.Status.Value = "Hero"

Here is another way to do it that doesn't involve the icky repeat until loop:

players = {}
for _,v in pairs (game.Players:GetChildren()) do
        table.insert(players, v.Name)
end
local randomIndex = math.random(1,#players) ;
chosenplayerone = game.Players:FindFirstChild( players[randomIndex] );
table.remove(players,randomIndex); -- Remove the first person we picked
chosenplayertwo = game.Players:FindFirstChild( players[math.random(1,#players)] );
chosenplayerone.Status.Value = "Vigilante"
chosenplayertwo.Status.Value = "Hero"

We can make this still shorter by realizing that game.Players:GetChildren() already stores a list of players! This eliminates the loop as well as the calls to FindFirstChild:

players = game.Players:GetChildren();

local randomIndex = math.random(1,#players);
chosenplayerone = players[randomIndex];
table.remove(players,randomIndex); -- Remove the first person we picked
chosenplayertwo = players[math.random(1,#players)];
chosenplayerone.Status.Value = "Vigilante"
chosenplayertwo.Status.Value = "Hero"

Answer this question