AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Scripting Help (https://forums.alliedmods.net/forumdisplay.php?f=11)
-   -   [code] infinity loop (https://forums.alliedmods.net/showthread.php?t=276774)

JusTGo 12-28-2015 04:15

[code] infinity loop
 
PHP Code:

GetRandomPlayer()
{
    static 
iPlayerBitsi
    
    
//Make a bitsum of connected player indexes. 
    //You can add additional checks here (bot,team,admin, etc).
    
for ( <= g_iMaxPlayers i++ )
        if ( 
IsSetBit(g_iBitUserAlive) && g_iUserTeam[i] == )
            
iPlayerBits |= ( << ( ) );
    
    
//No players are connected.
    
if ( !iPlayerBits )
        return 
0;
    
    
//Keep looping until there is no players that haven't been selected.
    
while( iPlayerBits != g_Selected )
    {
        
//Get random player id
        
= ( random_numg_iMaxPlayers ) - );
        
        
//If player is connected and has not yet been selected
        
if ( ( iPlayerBits & ( << ) ) && !( g_Selected & ( << ) ) )
        {
            
//Set bit in g_Selected bit-field so they will be ignored on the next call
            
g_Selected |= ( << );
            return ( 
);
        }
    }
    
    
//All players have already been selected.
    
g_Selected 0;
    return 
GetRandomPlayer()


some times randomly this code make infinity loop i took it from here https://forums.alliedmods.net/showth...634#post829634 i m trying to make it automatically reset selected players when all players have been selected.

addons_zz 12-28-2015 09:20

Re: [code] infinity loop
 
The correct code was posted later on that thread.

Here I adapted it to reset the index after the first time select all players, when you call display_random_reset( id ):

Spoiler

JusTGo 12-28-2015 14:12

Re: [code] infinity loop
 
Quote:

Originally Posted by addons_zz (Post 2377245)
The correct code was posted later on that thread.

Here I adapted it to reset the index after the first time select all players, when you call display_random_reset( id ):

Code:
#include <amxmodx> #include <amxmisc> #define PLUGIN  "Get Random Player" #define VERSION "1.0" #define AUTHOR  "bugsy" new g_Players;     //Bit-field of players currently connected new g_Selected;    //Bit-field of players that have already been selected randomly new g_Min;         //The current lowest connected ID [usually will be 1] new g_Max;         //The current highest connected ID [can range from 1 to g_MaxPlayers] new g_MaxPlayers; public plugin_init() {     register_plugin( PLUGIN, VERSION, AUTHOR );         register_concmd( "display_random", "display_random" );     register_concmd( "reset_random", "reset_random" );     register_concmd( "display_random_reset", "display_random_reset" );         g_MaxPlayers = get_maxplayers(); } public display_random( id ) {     server_print( "Random ID = %d ~ g_Min = %d ~ g_Max = %d", GetRandomPlayer(), g_Min, g_Max ); } public reset_random( id ) {     ResetSelected(); } public display_random_reset( id ) {     new random = GetRandomPlayer()         server_print( "Random ID = %d ~ g_Min = %d ~ g_Max = %d", random, g_Min, g_Max );     if( random == 0 )     {         ResetSelected()     } } public client_connect( id ) {     //Player has connected, add their ID to g_Players bit-field     g_Players |= ( 1 << ( id - 1 ) );         //Determine new min and max current ID     GetMaxMin( g_Min, g_Max ); } public client_disconnect( id ) {     //Player has disconnected, clear their ID from g_Players and g_Selected bit-field     g_Selected &= ~( 1 << ( id - 1 ) );     g_Players  &= ~( 1 << ( id - 1 ) );         //Determine new min and max current ID     GetMaxMin( g_Min, g_Max ); } GetMaxMin( &iMin, &iMax ) {     for( new i = 0; i < g_MaxPlayers; i++ )     {         if( g_Players & ( 1 << i ) )         {             if( i < iMin )             {                 iMin = i;             }                         if( i > iMax )             {                 iMax = i;             }         }     } } ResetSelected() {     g_Selected = 0; } GetRandomPlayer() {     //No players are connected or all have been selected already     if( !g_Players         || ( g_Players == g_Selected ) )     {         return 0;     }         new iRandomID;         //Keep looping while there is players that haven't yet been selected.     while( g_Players != g_Selected )     {         //Get random player id         iRandomID = random_num( g_Min, g_Max );                 //If player is connected and has not yet been selected         if( ( g_Players & ( 1 << iRandomID ) )             && !( g_Selected & ( 1 << iRandomID ) ) )         {             //Set bit for this ID in g_Selected bit-field so the player will now be considered selected             g_Selected |= ( 1 << iRandomID );             return ( iRandomID + 1 );         }     }         //All players have already been selected.     return 0; }

ty for helping but in :
PHP Code:

public display_random_resetid )
{
    new 
random GetRandomPlayer()
    
    
server_print"Random ID = %d ~ g_Min = %d ~ g_Max = %d"randomg_Ming_Max );

    if( 
random == )
    {
        
ResetSelected()
    }


when all players selected it will show 0 and then you need to call it again to show a random number can you help making never shows 0.

addons_zz 12-28-2015 14:58

Re: [code] infinity loop
 
Quote:

Originally Posted by JusTGo (Post 2377379)
when all players selected it will show 0 and then you need to call it again to show a random number can you help making never shows 0.

Done.

Code:
public display_random_reset( id ) {     new random = GetRandomPlayer()     if( random == 0 )     {         ResetSelected()         random = GetRandomPlayer()     }     server_print( "Random ID = %d ~ g_Min = %d ~ g_Max = %d", random, g_Min, g_Max ); }

JusTGo 12-29-2015 07:39

Re: [code] infinity loop
 
Quote:

Originally Posted by addons_zz (Post 2377394)
Done.

Code:
public display_random_reset( id ) {     new random = GetRandomPlayer()     if( random == 0 )     {         ResetSelected()         random = GetRandomPlayer()     }     server_print( "Random ID = %d ~ g_Min = %d ~ g_Max = %d", random, g_Min, g_Max ); }

ty again i edited it a bit cause when no players connected it will print 0 is this right ?

Code:
public display_random_reset( id ) {     new random = GetRandomPlayer()     // all players have been selected clearing selection and picking a new random     if( random == -1 )     {         ResetSelected()         random = GetRandomPlayer()         if(random)             server_print( "Random ID = %d ~ g_Min = %d ~ g_Max = %d", random, g_Min, g_Max );     }     else if (random == 0)     {     server_print( "No players Found" );         ResetSelected() // no players in server or met the rules of selection     }     else     {         server_print( "Random ID = %d ~ g_Min = %d ~ g_Max = %d", random, g_Min, g_Max );     } }


Code:
GetRandomPlayer() {     //No players are connected or all have been selected already     if( !g_Players         || ( g_Players == g_Selected ) )     {         return 0; // no players to select     }         new iRandomID;         //Keep looping while there is players that haven't yet been selected.     while( g_Players != g_Selected )     {         //Get random player id         iRandomID = random_num( g_Min, g_Max );                 //If player is connected and has not yet been selected         if( ( g_Players & ( 1 << iRandomID ) )             && !( g_Selected & ( 1 << iRandomID ) ) )         {             //Set bit for this ID in g_Selected bit-field so the player will now be considered selected             g_Selected |= ( 1 << iRandomID );             return ( iRandomID + 1 );         }     }         //All players have already been selected.     return -1; // making this -1 so we now we will know when all players are selected }

edit:
is this the right way of making to pick from specific team ?
Code:
GetMaxMin( &iMin, &iMax ) {     for( new i = 0; i < g_MaxPlayers; i++ )     {         if( g_Players & ( 1 << i ) && is_user_alive(i) && cs_get_user_team(i) == CS_TEAM_CT )         {             if( i < iMin )             {                 iMin = i;             }                         if( i > iMax )             {                 iMax = i;             }         }     } }

addons_zz 12-29-2015 17:02

Re: [code] infinity loop
 
1 Attachment(s)
Quote:

Originally Posted by JusTGo (Post 2377633)
ty again i edited it a bit cause when no players connected it will print 0 is this right ?

Yes. Nice work.

Quote:

Originally Posted by JusTGo (Post 2377633)
is this the right way of making to pick from specific team ?
Code:
GetMaxMin( &iMin, &iMax ) {     for( new i = 0; i < g_MaxPlayers; i++ )     {         if( g_Players & ( 1 << i ) && is_user_alive(i) && cs_get_user_team(i) == CS_TEAM_CT )         {             if( i < iMin )             {                 iMin = i;             }                         if( i > iMax )             {                 iMax = i;             }         }     } }

Do not mix the min and max ids with player team. Why do you checked if the player was alive? Dead players do not have team?
If the player was not connect, he would not be selected because every time he disconnect/connect he is added/removed from the selection.

The better point I think to do this is here:
Code:
GetRandomPlayer() {     //No players are connected or all have been selected already     if( !g_Players         || ( g_Players == g_Selected ) )     {         return 0;     }         new iRandomID;         //Keep looping while there is players that haven't yet been selected.     while( g_Players != g_Selected )     {         //Get random player id         iRandomID = random_num( g_Min, g_Max );                 //If player is connected and has not yet been selected         if( ( g_Players & ( 1 << iRandomID ) )             && !( g_Selected & ( 1 << iRandomID ) ) )         {             //Set bit for this ID in g_Selected bit-field so the player will now be considered selected             g_Selected |= ( 1 << iRandomID );                         if( cs_get_user_team( iRandomID + 1 ) == CS_TEAM_CT )             {                 return ( iRandomID + 1 );             }             else             {                 return GetRandomPlayer()             }         }     }         //All players have already been selected.     return -1; // making this -1 so we now we will know when all players are selected }
I attached the full code.

JusTGo 12-30-2015 06:03

Re: [code] infinity loop
 
Quote:

Originally Posted by addons_zz (Post 2377836)
Yes. Nice work.


Do not mix the min and max ids with player team. Why do you checked if the player was alive? Dead players do not have team?
If the player was not connect, he would not be selected because every time he disconnect/connect he is added/removed from the selection.



I attached the full code.

ty again, i need the played to be alive && ct same time cause he can be in ct team and his dead so i used:
Code:
GetRandomPlayer() {     //No players(alive && ct) or all have been selected already     if( !g_Players || !GetAliveCt()         /*|| ( g_Players == g_Selected )*/ ) // so it will not return 0 when all players selected selected.     {         return 0;     }         new iRandomID;         //Keep looping while there is players that haven't yet been selected.     while( g_Players != g_Selected )     {         //Get random player id         iRandomID = random_num( g_Min, g_Max );                 //If player is connected and has not yet been selected         if( ( g_Players & ( 1 << iRandomID ) )             && !( g_Selected & ( 1 << iRandomID ) ) )         {             //Set bit for this ID in g_Selected bit-field so the player will now be considered selected             g_Selected |= ( 1 << iRandomID );                         if( is_user_alive( iRandomID + 1 ) && cs_get_user_team( iRandomID + 1 ) == CS_TEAM_CT )             {                 return ( iRandomID + 1 );             }             else             {                 return GetRandomPlayer()             }         }     }         //All players have already been selected.     /*if( g_Players == g_Selected )*/ // no need for this check the while loop will already do that for us.     return -1; // making this -1 so we now we will know when all players are selected } GetAliveCt() {     new iCt, id         for (id = 1; id <= g_MaxPlayers; id++)     {         if (is_user_alive( id ) && cs_get_user_team( id ) == CS_TEAM_CT)             iCt++     }         return iCt; }

its working perfect now but just some small issuses like for ex:
you call radom 3 times it gives you: 7 3 1 the you call it another time it gives your 7 3 1 its rare but happens or other thing for ex you get: 7 3 1 next time you do random you get 1 7 3 so you have the number 1 selected twice in a row but i guess thats how random_num() works.

edit:
https://forums.alliedmods.net/showpo...91&postcount=7
Code:
GetMaxMin( &iMin, &iMax ) {     for( new i = 0; i < g_MaxPlayers; i++ )     {         if( g_Players & ( 1 << i ) )         {             if( i < iMin )             {                 iMin = i;             }                         if( i > iMax )             {                 iMax = i;             }         }     } }

is this okay ?

addons_zz 12-30-2015 07:57

Re: [code] infinity loop
 
Quote:

Originally Posted by JusTGo (Post 2377998)
i need the played to be alive && ct same time cause he can be in ct team and his dead so i used:
Code:
GetRandomPlayer() {     //No players(alive && ct) or all have been selected already     if( !g_Players || !GetAliveCt()         /*|| ( g_Players == g_Selected )*/ ) // so it will not return 0 when all players selected selected.     {         return 0;     }

its working perfect now but just some small issuses like for ex:
you call radom 3 times it gives you: 7 3 1 the you call it another time it gives your 7 3 1 its rare but happens or other thing for ex you get: 7 3 1 next time you do random you get 1 7 3 so you have the number 1 selected twice in a row but i guess thats how random_num() works.

Nice work. And you can remove the ( g_Players == g_Selected ), because, if all are already selected, should return -1, instead of 0.
Code:
GetRandomPlayer() {     //No players (alive && ct)     if( !g_Players       || !GetAliveCt() ) // so it will not return 0 when there is no players to be selected.     {         return 0;     }

Quote:

Originally Posted by JusTGo (Post 2377998)
Code:
GetMaxMin( &iMin, &iMax ) {     for( new i = 0; i < g_MaxPlayers; i++ )     {         if( g_Players & ( 1 << i ) )         {             if( i < iMin )             {                 iMin = i;             }                         if( i > iMax )             {                 iMax = i;             }         }     } }

is this okay ?

Yes.

Your function GetAliveCt() do not need to count all cts, unless you need the total alive. Then it just could be:
Code:
GetAliveCt() {     for( new id = 1; id <= g_Max; id++ )     {         if ( is_user_alive( id )            && cs_get_user_team( id ) == CS_TEAM_CT )         {             return 1         }     }     return 0; }

But is you need all alive CTs total and their ids, you can use a built-in function which should be faster:
Code:
new players_CT_ids[32] new players_total_CT_number get_players(players_CT_ids, players_total_CT_number, "ae", "CT")
Quote:

Originally Posted by https://www.amxmodx.org/api/amxmodx/get_players
Optional list of filtering flags:
"a" - do not include dead clients
...
"e" - match with team


JusTGo 12-30-2015 08:06

Re: [code] infinity loop
 
Quote:

Originally Posted by addons_zz (Post 2378036)
Nice work. And you can remove the ( g_Players == g_Selected ), because, if all are already selected, should return -1, instead of 0.
Code:
GetRandomPlayer() {     //No players (alive && ct)     if( !g_Players       || !GetAliveCt() ) // so it will not return 0 when there is no players to be selected.     {         return 0;     }

i put it between /**/ forgot to delete it.

Quote:

Originally Posted by addons_zz (Post 2378036)
Your function GetAliveCt() do not need to count all cts, unless you need the total alive. Then it just could be:
Code:
GetAliveCt() {     for( new id = 1; id <= g_Max; id++ )     {         if ( is_user_alive( id )            && cs_get_user_team( id ) == CS_TEAM_CT )         {             return 1         }     }     return 0; }

oh didn't think about that i will use this from now :)

Quote:

Originally Posted by addons_zz (Post 2378036)
But is you need all alive CTs total and their ids, you can use a built-in function which should be faster:
Code:
new players_CT_ids[32] new players_total_CT_number get_players(players_CT_ids, players_total_CT_number, "ae", "CT")

but i remember get_players with e flag bugs.(i used to have a plugin that use get_players with e flag on amxx 1.8.2 and it randomly bugs and the number of players returned is 0.)

GuskiS 12-30-2015 10:05

Re: [code] infinity loop
 
If you still need help, check my signature for TTT mod, where I get all players and then randomly assign them roles and make sure all of them have a role at the end.


All times are GMT -4. The time now is 17:57.

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