Liberty Unleashed

Scripting => Script Snippets => Topic started by: himselfe on March 01, 2011, 12:48:28 am

Title: Get a list of players as a table.
Post by: himselfe on March 01, 2011, 12:48:28 am
Code: (squirrel) [Select]
function GetPlayersTable()
{
local players = {};

for (local player, id = 0, count = GetMaxPlayers(); id < count; id++)
if ((player = FindPlayer(id))) players.rawset(player.Name,player);

return players;
}

This function returns a Squirrel table (http://www.squirrel-lang.org/doc/squirrel2.html#d0e1303) containing a list of all the players currently on the server. This allows you to use foreach (http://www.squirrel-lang.org/doc/squirrel2.html#d0e778) to iterate through all the players on the server. For example:

Code: (squirrel) [Select]
local players = GetPlayersTable();

foreach(player in players)
player.Frozen = true;

The above code would freeze every player on the server. You can also check if a certain player is in the table by name:

Code: (squirrel) [Select]
function onPlayerCommand( player, cmd, args )
{
local players = GetPlayersTable();
local arglist = split( args, " " );

switch(cmd)
{
case "ouch":
local name = arglist[0];

local pos = player.Pos;
pos.z += 5;

if (name in players)
players[name].Pos = pos;

return 1;
}

return 0;
}

The above code would create a new command '/ouch' which a player could use to drop another player on their head by typing '/ouch someguy'.

An optimised way to handle player lists:

One potential efficiency problem with the GetPlayersTable() function above is that when using it in a foreach loop you will essentially be looping through the players list twice. One way to avoid this is to keep a global table containing an active list of players. Using GetPlayersTable() to populate a global table would not be sufficient as the list would become invalid as players join and part the server. A solution to this is to use the onPlayerJoin (http://liberty-unleashed.co.uk/LUWiki/Squirrel/Server/Events/Player/onPlayerJoin) and onPlayerPart (http://liberty-unleashed.co.uk/LUWiki/Squirrel/Server/Events/Player/onPlayerPart) callbacks to manage an active list of players:

Code: (squirrel) [Select]
players <- {};

function onPlayerJoin( player )
{
players.rawset(player.Name,player);
}

function onPlayerPart( player, reason )
{
players.rawdelete(player.Name);
}

This way the global 'players' table always contains a valid list of players currently on the server. You would then use this global table in the same way as above, but without the need to define it locally or call GetPlayersTable().
Title: Re: Get a list of players as a table.
Post by: Stoku on March 01, 2011, 10:27:50 am
Whoa, nice one!
Title: Re: Get a list of players as a table.
Post by: Windlord on March 01, 2011, 11:00:18 am
oh I meant to change GetPlayers to GetMaxPlayers but yeah, the caching to list method is good since there is no way of efficiently referring to players for looping methods within LU's implementation. :)

Note: Only just realised that this was meant for another topic. Please ignore the contents :)
Title: Re: Get a list of players as a table.
Post by: aXXo on July 27, 2011, 01:42:02 pm
Its a nice way to traverse through players.
Saves a lot of iterations when traversing through all players ingame :)

But theres a problem.

I want to access the global table declared in a .nut file, in a different .nut file.
It shows an error: "the index 'players' does not exist"

Is there any way to use these tables(or any other global variable) in more than one .nut files?
Title: Re: Get a list of players as a table.
Post by: Force on July 27, 2011, 02:59:04 pm
The best thing to do is to dofile scripts into the main script, that way you can spread a script over various files, whilst still sharing variables.
Title: Re: Get a list of players as a table.
Post by: aXXo on July 27, 2011, 05:56:16 pm
The global variables need to be in the main file?
Or any of the dofile'd files?
Title: Re: Get a list of players as a table.
Post by: Force on July 27, 2011, 08:48:44 pm
The global variables need to be in the main file?
Or any of the dofile'd files?

I do believe any file will be fine.