Callback problem
#1

I have the adri1 derby system, and I want to place a "GameTextForPlayer" in the "DerbyCountdown" callback, which does not have "playerid", so I do not know if it should be placed or it has to be a global callback.

PHP код:
public DerbyCountdown()
{
    if(
DI[STATUS] != DERBY_WAIT) return KillTimer(DI[COUNTDOWN_TIMER]);
    if(
DI[PLAYERS] <= 0) return CloseDerby();
    if(
DI[PLAYERS] == 1)
    {
        
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1;
        
GameTextForPlayer(playerid"~g~Waiting for players"5003); //<--------------
        
return 1;
    }
    
DI[COUNTDOWN_COUNTER] --;
    if(
DI[COUNTDOWN_COUNTER] <= 0)
    {
        
KillTimer(DI[COUNTDOWN_TIMER]);
        if(
DI[PLAYERS] == 0) return CloseDerby();
        else if(
DI[PLAYERS] == 1)
        {
            
GameTextForPlayer(playerid"~g~Waiting for players"5003); //<--------------
            
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1;
            
KillTimer(DI[COUNTDOWN_TIMER]);
            
DI[COUNTDOWN_TIMER] = SetTimer("DerbyCountdown"900true); //<--------------
        
}
        else 
StartDerby();
    }
    return 
1;

public DerbyCountdown() or public DerbyCountdown(playerid)?
Reply
#2

Or add several "for"?

PHP код:
public DerbyCountdown()
{
    if(
DI[STATUS] != DERBY_WAIT) return KillTimer(DI[COUNTDOWN_TIMER]);
    if(
DI[PLAYERS] <= 0) return CloseDerby();
    if(
DI[PLAYERS] == 1)
    {
        
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1;
        for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++)
        {
            if(
IsPlayerConnected(playerid))
            {
                if(
Player[playerid][Mode] == GAME_DERBY)
                {
                    
GameTextForPlayer(playerid"~g~Waiting for players"5003);
                }
            }
        }
        return 
1;
    }
    
DI[COUNTDOWN_COUNTER] --;
    for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++)
    {
        if(
IsPlayerConnected(playerid))
        {
            if(
Player[playerid][Mode] == GAME_DERBY)
            {
                new 
str[10]; format(str10"~r~%d_minutes_to_start"DI[COUNTDOWN_COUNTER]);
                
GameTextForPlayer(playeridstr10003); 
            }
        }
    }
    
    
    if(
DI[COUNTDOWN_COUNTER] <= 0)
    {
        
KillTimer(DI[COUNTDOWN_TIMER]);
        if(
DI[PLAYERS] == 0) return CloseDerby();
        else if(
DI[PLAYERS] == 1)
        {
            for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++)
            {
                if(
IsPlayerConnected(playerid))
                {
                    if(
Player[playerid][Mode] == GAME_DERBY)
                    {
                        
GameTextForPlayer(playerid"~g~Waiting for players"5003);
                    }
                }
            }
            
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1;
            
KillTimer(DI[COUNTDOWN_TIMER]);
            
DI[COUNTDOWN_TIMER] = SetTimer("DerbyCountdown"900true);
        }
        else 
StartDerby();
    }
    return 
1;

Reply
#3

When you're handling playerid, your procedure should have at minimum 1 parameter, being playerid.

You do not need any loops for that procedure. "playerid" does not need to have a loop in order to use it. You only ever need to use custom playerids when you want to produce a target ID. Even then, you'd use sscanf to evaluate the specific ID you want.

Top tip: Design your functionality before you implement it.
Reply
#4

Quote:
Originally Posted by sammp
Посмотреть сообщение
When you're handling playerid, your procedure should have at minimum 1 parameter, being playerid.

You do not need any loops for that procedure. "playerid" does not need to have a loop in order to use it. You only ever need to use custom playerids when you want to produce a target ID. Even then, you'd use sscanf to evaluate the specific ID you want.

Top tip: Design your functionality before you implement it.
So I must use "public DerbyCountdown(playerid)"?
Reply
#5

Quote:
Originally Posted by SapMan
Посмотреть сообщение
So I must use "public DerbyCountdown(playerid)"?
Yes, you must have a parameter in this callback.
Reply
#6

Quote:
Originally Posted by iHollyZinhO
Посмотреть сообщение
Yes, you must have a parameter in this callback.
This callback isn't called per-player. It's the countdown callback which gets called for everyone, thus there must be a loop iterating through all players that are inside the derby.

Just adding playerid as parameter will do nothing. This code isn't meant to be called for every player.
Reply
#7

So what should I do exactly, add "for(new playerid = 0, j = GetPlayerPoolSize(); playerid <= j; playerid++) "?
Reply
#8

Quote:
Originally Posted by SapMan
Посмотреть сообщение
So what should I do exactly, add "for(new playerid = 0, j = GetPlayerPoolSize(); playerid <= j; playerid++) "?
Код:
for(new xx = 0; xx < MAX_PLAYERS; xx++)
Use xx instead of playerid in that callback and also check for the players who all are in the derby(assume that Inderby[playerid] is the variable that consider that the player is in the derby).

Example:
Код:
public DerbyCountdown() 
{ 
      for(new xx = 0; xx < MAX_PLAYERS; xx++) 
      {
          if(Inderby[xx] == 1) // Check the players who all are in derby.
          {

                //=== codes

           }
       }
        return 1;
}
Reply
#9

Quote:
Originally Posted by NaS
Посмотреть сообщение
This callback isn't called per-player. It's the countdown callback which gets called for everyone, thus there must be a loop iterating through all players that are inside the derby.

Just adding playerid as parameter will do nothing. This code isn't meant to be called for every player.
Should I use this?

PHP код:
public DerbyCountdown() 

    if(
DI[STATUS] != DERBY_WAIT) return KillTimer(DI[COUNTDOWN_TIMER]); 
    if(
DI[PLAYERS] <= 0) return CloseDerby(); 
    if(
DI[PLAYERS] == 1
    { 
        
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
        for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
        { 
            if(
IsPlayerConnected(playerid)) 
            { 
                if(
Player[playerid][Mode] == GAME_DERBY
                { 
                    
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                } 
            } 
        } 
        return 
1
    } 
    
DI[COUNTDOWN_COUNTER] --; 
    for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
    { 
        if(
IsPlayerConnected(playerid)) 
        { 
            if(
Player[playerid][Mode] == GAME_DERBY
            { 
                new 
str[10]; format(str10"~r~%d_minutes_to_start"DI[COUNTDOWN_COUNTER]); 
                
GameTextForPlayer(playeridstr10003);  
            } 
        } 
    } 
     
     
    if(
DI[COUNTDOWN_COUNTER] <= 0
    { 
        
KillTimer(DI[COUNTDOWN_TIMER]); 
        if(
DI[PLAYERS] == 0) return CloseDerby(); 
        else if(
DI[PLAYERS] == 1
        { 
            for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
            { 
                if(
IsPlayerConnected(playerid)) 
                { 
                    if(
Player[playerid][Mode] == GAME_DERBY
                    { 
                        
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                    } 
                } 
            } 
            
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
            
KillTimer(DI[COUNTDOWN_TIMER]); 
            
DI[COUNTDOWN_TIMER] = SetTimer("DerbyCountdown"900true); 
        } 
        else 
StartDerby(); 
    } 
    return 
1

Reply
#10

Quote:
Originally Posted by UFF
Посмотреть сообщение
Код:
for(new xx = 0; xx < MAX_PLAYERS; xx++)
This loop is not optimized, it loops for MAX_PLAYERS time which is 1000 if not changed.
for(new playerid = 0, j = GetPlayerPoolSize(); playerid <= j; playerid++) is alot better, it loops only through the connected players
Reply
#11

That is, I must use three times "for (new i = 0, j = GetPlayerPoolSize (); i <= j; i ++)"?

PHP код:
public DerbyCountdown() 

    if(
DI[STATUS] != DERBY_WAIT) return KillTimer(DI[COUNTDOWN_TIMER]); 
    if(
DI[PLAYERS] <= 0) return CloseDerby(); 
    if(
DI[PLAYERS] == 1
    { 
        
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
        for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
        { 
            if(
IsPlayerConnected(playerid)) 
            { 
                if(
Player[playerid][Mode] == GAME_DERBY
                { 
                    
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                } 
            } 
        } 
        return 
1
    } 
    
DI[COUNTDOWN_COUNTER] --; 
    for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
    { 
        if(
IsPlayerConnected(playerid)) 
        { 
            if(
Player[playerid][Mode] == GAME_DERBY
            { 
                new 
str[10]; format(str10"~r~%d_minutes_to_start"DI[COUNTDOWN_COUNTER]); 
                
GameTextForPlayer(playeridstr10003);  
            } 
        } 
    } 
     
     
    if(
DI[COUNTDOWN_COUNTER] <= 0
    { 
        
KillTimer(DI[COUNTDOWN_TIMER]); 
        if(
DI[PLAYERS] == 0) return CloseDerby(); 
        else if(
DI[PLAYERS] == 1
        { 
            for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
            { 
                if(
IsPlayerConnected(playerid)) 
                { 
                    if(
Player[playerid][Mode] == GAME_DERBY
                    { 
                        
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                    } 
                } 
            } 
            
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
            
KillTimer(DI[COUNTDOWN_TIMER]); 
            
DI[COUNTDOWN_TIMER] = SetTimer("DerbyCountdown"900true); 
        } 
        else 
StartDerby(); 
    } 
    return 
1

Please, I need a quick help.
Reply
#12

Quote:
Originally Posted by SapMan
Посмотреть сообщение
That is, I must use three times "for (new i = 0, j = GetPlayerPoolSize (); i <= j; i ++)"?

PHP код:
public DerbyCountdown() 

    if(
DI[STATUS] != DERBY_WAIT) return KillTimer(DI[COUNTDOWN_TIMER]); 
    if(
DI[PLAYERS] <= 0) return CloseDerby(); 
    if(
DI[PLAYERS] == 1
    { 
        
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
        for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
        { 
            if(
IsPlayerConnected(playerid)) 
            { 
                if(
Player[playerid][Mode] == GAME_DERBY
                { 
                    
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                } 
            } 
        } 
        return 
1
    } 
    
DI[COUNTDOWN_COUNTER] --; 
    for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
    { 
        if(
IsPlayerConnected(playerid)) 
        { 
            if(
Player[playerid][Mode] == GAME_DERBY
            { 
                new 
str[10]; format(str10"~r~%d_minutes_to_start"DI[COUNTDOWN_COUNTER]); 
                
GameTextForPlayer(playeridstr10003);  
            } 
        } 
    } 
     
     
    if(
DI[COUNTDOWN_COUNTER] <= 0
    { 
        
KillTimer(DI[COUNTDOWN_TIMER]); 
        if(
DI[PLAYERS] == 0) return CloseDerby(); 
        else if(
DI[PLAYERS] == 1
        { 
            for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
            { 
                if(
IsPlayerConnected(playerid)) 
                { 
                    if(
Player[playerid][Mode] == GAME_DERBY
                    { 
                        
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                    } 
                } 
            } 
            
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
            
KillTimer(DI[COUNTDOWN_TIMER]); 
            
DI[COUNTDOWN_TIMER] = SetTimer("DerbyCountdown"900true); 
        } 
        else 
StartDerby(); 
    } 
    return 
1

Please, I need a quick help.
This code looks fine, did you find a problem with it?
Reply
#13

No, but something tells me that using three "loops" is not a good way and it can be done in a better way, but I do not know how.
Reply
#14

Assuming you're setting variable [Mode] to GAME_DERBY when someone joins a derby, the code can be shortened in this way:

pawn Код:
foreach (new i : Player) if (Player[i][Mode] == GAME_DERBY) GameTextForPlayer(playerid, "~g~Waiting for players", 500, 3);
Also, i suggest you to use y_timers.
Reply
#15

No, foreach is not widely used and I do not like it, besides "GetPlayerPoolSize" only travels through the connected players.
Reply
#16

Quote:
Originally Posted by SapMan
Посмотреть сообщение
No, foreach is not widely used and I do not like it, besides "GetPlayerPoolSize" only travels through the connected players.
No sir. GetPlayerPoolSize give you the hightest id of connected players. You need to loop through ID 0 to this ID and check is every id is a bot nor is connected.
Foreach (Player - which is an iterator ; it exists Actor and NPC) doesn't do that. It loop through all connected players only. y_iterate allows you to use iterator. You can take look here if you are interested: https://sampforum.blast.hk/showthread.php?tid=570937
Reply
#17

Quote:
Originally Posted by Dayrion
Посмотреть сообщение
No sir. GetPlayerPoolSize give you the hightest id of connected players. You need to loop through ID 0 to this ID and check is every id is a bot nor is connected.
Foreach (Player - which is an iterator ; it exists Actor and NPC) doesn't do that. It loop through all connected players only. y_iterate allows you to use iterator. You can take look here if you are interested: https://sampforum.blast.hk/showthread.php?tid=570937
This.
Reply
#18

It is concerned if it is not a bad way to use 3 "loops" in the same callback.
Reply
#19

Quote:
Originally Posted by SapMan
Посмотреть сообщение
That is, I must use three times "for (new i = 0, j = GetPlayerPoolSize (); i <= j; i ++)"?

Please, I need a quick help.
You can add a check to the second loop.

That way only one of those loops will ever be executed at once (so technically it's just one loop per execution).

Even if it were 3, those aren't very complex loops so I don't see how there would be any issues.

PHP код:
public DerbyCountdown() 

    if(
DI[STATUS] != DERBY_WAIT) return KillTimer(DI[COUNTDOWN_TIMER]); 
    if(
DI[PLAYERS] <= 0) return CloseDerby(); 
    if(
DI[PLAYERS] == 1
    { 
        
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
        for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
        { 
            if(
IsPlayerConnected(playerid)) 
            { 
                if(
Player[playerid][Mode] == GAME_DERBY
                { 
                    
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                } 
            } 
        } 
        return 
1
    } 
    
DI[COUNTDOWN_COUNTER] --; 
    if(
DI[COUNTDOWN_COUNTER] > 0)
    { 
        for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++)
        { 
            if(
IsPlayerConnected(playerid)) 
            { 
                if(
Player[playerid][Mode] == GAME_DERBY
                { 
                    new 
str[10]; format(str10"~r~%d_minutes_to_start"DI[COUNTDOWN_COUNTER]); 
                    
GameTextForPlayer(playeridstr10003);  
                } 
            } 
        } 
    }
    else
    { 
        
KillTimer(DI[COUNTDOWN_TIMER]); 
        if(
DI[PLAYERS] == 0) return CloseDerby(); 
        else if(
DI[PLAYERS] == 1
        { 
            for(new 
playerid 0GetPlayerPoolSize(); playerid <= jplayerid++) 
            { 
                if(
IsPlayerConnected(playerid)) 
                { 
                    if(
Player[playerid][Mode] == GAME_DERBY
                    { 
                        
GameTextForPlayer(playerid"~g~Waiting for players"5003); 
                    } 
                } 
            } 
            
DI[COUNTDOWN_COUNTER] = DERBY_TIME_COUNTDOWN 1
            
KillTimer(DI[COUNTDOWN_TIMER]); 
            
DI[COUNTDOWN_TIMER] = SetTimer("DerbyCountdown"900true); 
        } 
        else 
StartDerby(); 
    } 
    return 
1

The second loop doesn't need to be executed when the time reached 0, since you want to start the derby at that moment.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)