I'm trying to loop through active players in turn in order to determine whos turn it is next, but I'm having a bit of a logic block. I could be trying to do something really stupid here, can anyone help me out?
Sorry for the poor explanation! I am trying to target players by client in order to give a special weapon for X seconds.
Alice, Bob, Charlie and Dave are playing in a server on team 2 against bots. I want a function which can help me find out whos turn it is to have the weapon. In no particular order, I want to give everybody the weapon. If they are dead, ignore them and give it to the next player. Once everybody has had it (except anyone who was dead when it was their turn), give it back to the player who had it first, then continue. If a new player connects, include them in the scheme.
I want to be able to run the function whenever I want. Maybe I want charlie to have the weapon for two turns, so the nextplayer variable should be global.
Thankyou!
EDIT: Okay I think I got it. Well, it works in some early testing but if anyone knows how to improve the code that would be useful! Thanks
Code:
int nextclient;
OnMapStart()
{
nextclient = 0;
}
public void GetNextClient()
{
if(nextclient ==0)
{
nextclient = 1; // If its been run first time on the map, just grab first slot
}
for(int i = nextclient; i <= MaxClients; i++) // start the loop from where we left off - at the last set nextclient
{
if(IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && !IsFakeClient(i) && nextclient != i) // Exclude the last set nextclient from our loop
{
nextclient = i; // We found a client so set them, and exit function
return;
}
else
{
// We got no one, so carry on with loop or continue
}
}
// Exited resumed loop - either the last nextclient was the last client in the client array, or the last clients checked were unsuitable, so lets start again with a fresh loop
for(int i = 1; i <= MaxClients; i++)
{
if(IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && !IsFakeClient(i)) // We let the last nextclient participate in this loop
{
nextclient = i; // We found a client so set them, and exit function
return;
}
else
{
// We got no one, so carry on with the resetted loop or continue
}
}
// Okay so we found no-one suitable in the server so who cares
}
This one you can ignore, but I wanted to show anyway.
This look next index from previous one, loop back to start from 1, stop on old index. Similiar as yours.
not important
PHP Code:
int GetNextHumanPlayer(int team = -1, int custom_offset = -1)
{
// This local variable keep record of previous index
static int offset = 0;
// When use given custom index
if(custom_offset > 0 && custom_offset <= MaxClients)
offset = custom_offset;
int i = offset+1;
// Reset index when out of boundary
if(i > MaxClients || i < 1)
i = 1;
// collect players in array
int[] targets = new int[MaxClients];
int count;
for( ; ; i++)
{
// check, if index goes out of boundary
if(i > MaxClients)
{
// when offset have a valid value, reset index. Otherwise stop loop.
if(offset > 0 && offset <= MaxClients)
{
i = 1;
}
else
{
break;
}
}
// We find human player
if(IsClientInGame(i) && !IsFakeClient(i))
{
// team index either have set or not
if( team == -1 || GetClientTeam(i) == team)
{
targets[count] = i;
count++;
}
}
// stop loop when match old index;
if(i == offset)
break;
}
// No single human player found
if(count == 0)
return -1;
// Lets use one, first value from array. It's either same index or next one
offset = targets[0];
return offset;
}
In this version, it can use either client index or client UserID
- This collect matching targets into array and sort array by ascending method. (0,1,2,3,4,5 ...)
But when using this one same function, use only same type, either client index or userid.
Not both or you can not get right result.
To able to use both, you need dublicate function and rename it.
For looking client index, from team 2 "terrorists":
int player = GetNextHumanPlayer(2);
PHP Code:
#include <cstrike>
public void OnPluginStart()
{
RegConsoleCmd("sm_test", test);
}
public Action test(int client, int args)
{
int player;
player = GetNextHumanPlayer(.UseUserID = true);
player = GetClientOfUserId(player);
if(player)
PrintToServer("GetNextHumanPlayer(UseUserID) index %i (%N)", player, player);
return Plugin_Handled;
}
int GetNextHumanPlayer(int team = -1, bool UseUserID = false)
{
static int offset = 0;
int[] targets = new int[MaxClients];
int count;
for(int i = 1; i <= MaxClients; i++)
{
if(!IsClientInGame(i) || IsFakeClient(i))
continue;
for(int x = 0; x < count; x++)
{
if(offset < targets[x])
{
offset = targets[x];
return offset;
}
}
offset = targets[0];
return offset == 0 ? -1:offset;
}
Here is demonstration with bots, using UserID without team index:
player = GetNextHumanPlayer(.UseUserID = true);
Code:
# userid name uniqueid connected ping loss state adr
# 24 "Dean" BOT active
# 25 "Eric" BOT active
# 26 "Dustin" BOT active
# 17 "Tim" BOT active
# 20 "Colin" BOT active
# 21 "Nate" BOT active
# 22 "Grant" BOT active
# 23 "Paul" BOT active
# 27 "Alfred" BOT active
# 28 "Xander" BOT active
# 29 "Greg" BOT active
# 30 "Perry" BOT active
# 31 "Xavier" BOT active
# 32 "'Bacardi" [U:1:28327177] 23:49 34 0 active 192.168.1.2:27006
sm_test
GetNextHumanPlayer index 1 (Dean)
sm_test
GetNextHumanPlayer index 2 (Eric)
sm_test
GetNextHumanPlayer index 3 (Dustin)
sm_test
GetNextHumanPlayer index 4 (Tim)
sm_test
GetNextHumanPlayer index 5 (Colin)
sm_test
GetNextHumanPlayer index 6 (Nate)
sm_test
GetNextHumanPlayer index 7 (Grant)
sm_test
GetNextHumanPlayer index 8 (Paul)
sm_test
GetNextHumanPlayer index 9 (Alfred)
sm_test
GetNextHumanPlayer index 10 (Xander)
sm_test
GetNextHumanPlayer index 11 (Greg)
sm_test
GetNextHumanPlayer index 12 (Perry)
sm_test
GetNextHumanPlayer index 13 (Xavier)
sm_test
GetNextHumanPlayer index 14 ('Bacardi)
sm_test
GetNextHumanPlayer index 1 (Dean)
sm_test
GetNextHumanPlayer index 2 (Eric)
sm_test
GetNextHumanPlayer index 3 (Dustin)
sm plugins reload new
[SM] Plugin new.smx reloaded successfully.
sm_test
GetNextHumanPlayer(UseUserID) index 4 (Tim)
sm_test
GetNextHumanPlayer(UseUserID) index 5 (Colin)
sm_test
GetNextHumanPlayer(UseUserID) index 6 (Nate)
sm_test
GetNextHumanPlayer(UseUserID) index 7 (Grant)
sm_test
GetNextHumanPlayer(UseUserID) index 8 (Paul)
sm_test
GetNextHumanPlayer(UseUserID) index 1 (Dean)
sm_test
GetNextHumanPlayer(UseUserID) index 2 (Eric)
sm_test
GetNextHumanPlayer(UseUserID) index 3 (Dustin)
sm_test
GetNextHumanPlayer(UseUserID) index 9 (Alfred)
sm_test
GetNextHumanPlayer(UseUserID) index 10 (Xander)
sm_test
GetNextHumanPlayer(UseUserID) index 11 (Greg)
sm_test
GetNextHumanPlayer(UseUserID) index 12 (Perry)
sm_test
GetNextHumanPlayer(UseUserID) index 13 (Xavier)
sm_test
GetNextHumanPlayer(UseUserID) index 14 ('Bacardi)
sm_test
GetNextHumanPlayer(UseUserID) index 4 (Tim)
sm_test
GetNextHumanPlayer(UseUserID) index 5 (Colin)