Liberty Unleashed
Scripting => Script Snippets => Topic started by: himselfe on March 01, 2011, 12:48:28 am
-
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:
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:
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:
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().
-
Whoa, nice one!
-
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 :)
-
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?
-
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.
-
The global variables need to be in the main file?
Or any of the dofile'd files?
-
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.