AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting (https://forums.alliedmods.net/forumdisplay.php?f=107)
-   -   Solved [ANY]How can I loop through active players in turn? (https://forums.alliedmods.net/showthread.php?t=340610)

Morning 11-27-2022 17:59

[ANY]How can I loop through active players in turn?
 
Hi!

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?

Code:

int nextplayer = 1;
bool lastplayer = false;

void GetNextPlayer()
{
bool nextplayerset = false;
if(lastplayer)
        {
        nextplayer = 1;
        }
for(int i = 1; i <= MaxClients; i++)
        {
        if(i > 0 && i <= MaxClients && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && !IsFakeClient(i) && !nextplayerset)
                {
                nextplayer = i;
                nextplayerset = true;
                }
        if(i > 0 && i <= MaxClients && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && !IsFakeClient(i) && nextplayerset)
                {
                lastplayer = false;
                }
        else
                {
                lastplayer = true;
                }
        }
}

void GiveSomethingToPlayer()
{
        GetNextPlayer();
        GiveToPlayer(nextplayer);
}


Morning 11-27-2022 19:03

Re: [ANY]How can I loop through active players in turn?
 
Hmm, am I forgetting to break out of the loop? I shut down my server already so I cant test until tomorrow.

Code:

        if(i > 0 && i <= MaxClients && IsClientInGame(i) && GetClientTeam(i) == 2 && IsPlayerAlive(i) && !IsFakeClient(i) && nextplayerset)
                {
                lastplayer = false;
                break;
                }


alasfourom 11-27-2022 21:50

Re: [ANY]How can I loop through active players in turn?
 
May I know what are you exactly trying to do?

Can you provide me with more details I maybe able to help, give the whole picture if possible

Morning 11-28-2022 02:44

Re: [ANY]How can I loop through active players in turn?
 
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
}


Bacardi 11-28-2022 17:55

Re: [ANY]How can I loop through active players in turn?
 
Here is my testings.

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


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 clientint args)
{

    
int player;

    
player GetNextHumanPlayer(.UseUserID true);
    
    
player GetClientOfUserId(player);
    
    if(
player)
        
PrintToServer("GetNextHumanPlayer(UseUserID) index %i (%N)"playerplayer);

    return 
Plugin_Handled;
}



int GetNextHumanPlayer(int team = -1bool UseUserID false)
{
    static 
int offset 0;

    
int[] targets = new int[MaxClients];
    
int count;

    for(
int i 1<= MaxClientsi++)
    {
        if(!
IsClientInGame(i) || IsFakeClient(i))
            continue;
        
        if(
team != -&& GetClientTeam(i) != team)
            continue;

        
targets[count] = UseUserID GetClientUserId(i):i;
        
count++;
    }

    if(
count == 0)
        return -
1;

    
SortIntegers(targetscountSort_Ascending);


    for(
int x 0countx++)
    {
        if(
offset targets[x])
        {
            
offset targets[x];
            return 
offset;
        }
    }

    
offset targets[0];

    return 
offset == ? -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)


look, edit, test it.

Morning 11-28-2022 18:58

Re: [ANY]How can I loop through active players in turn?
 
Thanks for sharing this Bacardi! :twisted:


All times are GMT -4. The time now is 02:44.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.