Useful Functions

Quote:
Originally Posted by zLink
Посмотреть сообщение
List of admin commands

Log in rcon
( /rcon login [password] )
  • Pictures



  • Script
PHP код:
enum EnumAdminCommands {command[45],information[80]};
new const 
AdminCommands[][EnumAdminCommands] = //{"command","information"}
{
    {
"/Admincmd","List of commands for admin"},
    {
"/Example","This command does not exist!"},
    {
"/Example2","..."}
};
CMD:admincmd(playerid//using include izcmd
{
    if(!
IsPlayerAdmin(playerid)) //change
        
return 0;
    new 
ss[50],s[500];
    for(new 
isizeof(AdminCommands); i++)
    {
        
format(ss50"%s\n"AdminCommands[i][command]);
        
strcat(sss);
    }
    
ShowPlayerDialog(playerid888DIALOG_STYLE_LIST"Admin Commands"s"more""close");
    return 
1;
}
public 
OnDialogResponse(playeriddialogidresponselistiteminputtext[ ])
{
    if(
dialogid == 888)
    {
        if(!
response)
            return 
0;
        
        new 
s[80];
        for(new 
isizeof(AdminCommands); i++)
        if(
listitem == iformat(s80"%s"AdminCommands[i][information]);
        
        return 
ShowPlayerDialog(playerid889DIALOG_STYLE_MSGBOX"Admin Commands"s,"close","");
    }
    return 
0;

I was going to throw it in the trash, but it's a job.
Sorry for my english and if I posted on the wrong topic.
Oooor just:
PHP код:
public OnDialogResponse(playeriddialogidresponselistiteminputtext[ ]) 

    if(
dialogid == 888
        if(
response
              
ShowPlayerDialog(playerid889DIALOG_STYLE_MSGBOX"Admin Commands"AdminCommands[i][information], "Close",""); 

Don't return false if OnDialogResponse may be used somewhere else again.
Reply

Quote:
Originally Posted by Eoussama
View Post
Select Random Player
PHP Code:
stock SelectRandomPlayer()
{
    new 
GetPlayerPoolSize(),i,j,T[k];
    for(
i=0i<ki++){
        if(
IsPlayerConnected(i)){
            
T[j] = i;
            
j++;
        }
    }
    return 
T[random(j)];

PHP Code:
SelectRandomPlayer()
{
    new 
players[MAX_PLAYERS], count;
    for(new 
0GetPlayerPoolSize(); <= j++)
    {
        
IsPlayerConnected(i) && (players[count ++] = i);
    }
    return ((!
count) ? (-1) : (players[random(count)]));

Returns -1 if no players are connected.

Alternatively (for a tad better performance):
Quote:
Originally Posted by OneDay
View Post
PHP Code:
Iter_Random(Player); 
or

Have a global array store connected players and remove the ones that leave, filling the slots in a continuous order.
Reply

Quote:
Originally Posted by zLink
Посмотреть сообщение
no bump please.
Do you know what you're talking about?

@Edit I'm not a machine, just because you do it one way, and you think you're better.
This does not mean that you should force people to do the same.

https://sampwiki.blast.hk/wiki/OnDialogResponse
Just.. kys?
Reply

Useful
PHP код:
stock IsValidRPName(name[]) //credits: zLink and base Larceny
{
    if((
'A' <= name[0] <= 'Z') && ('a' <= name[1] <= 'z'))
    {
        if(
IsValidRPInput(name))
        {
            if(
strfind(name"_") != -1)
            {
                new 
underline strfind(name"_"), pos underline +1;
                if((
'A' <= name[pos] <= 'Z') && ('a' <= name[pos +1] <= 'z'))
                {
                    for(new 
istrlen(name); ++i)
                    {
                        if((
'A' <= name[i] <= 'Z') && (!= 0) && (!= pos)) return 0;
                        else if((
name[i] == '_') && (!= underline)) return 0;
                        else continue;
                    }
                    return 
1;
                }
            }
        }
    }
    return 
0;
}
IsValidRPInput(const ipstr[]) //credits: zLink and base PT
{
    for(new 
0ipstr[i] != EOS; ++i)
    {
        switch(
ipstr[i])
        {
            case 
'A'..'Z''a'..'z','_': continue;
            default: return 
0;
        }
    }
    return 
1;

Example
Код:
CMD:test(playerid, params[])
{
    if(isnull(params))
	return SendClientMessage(playerid, 0xFF0000FF,"use: /test [your name]");

    if(IsValidRPName(params))
    {
        //is valid
    }
    else
    {
        //not is valid
    }
    return 1;
}
Reply

Quote:
Originally Posted by Lokii
Посмотреть сообщение
Get weapon slot
Код:
stock GetWeaponSlot(weaponid)
{
    switch(weaponid)
    {
        case 0,1: return 0;
        case 2,3,4,5,6,7,8,9: return 1;
        case 10,11,12,13,14,15: return 10;
        case 16,17,18: return 8;
        case 22,23,24: return 2;
        case 25,26,27: return 3;
        case 28,29,32: return 4;
        case 30,31: return 5;
        case 33,34: return 6;
        case 35,36,37,38: return 7;
        case 39: return 8;
        case 40: return 12;
        case 41,42,43: return 9;
        case 44,45,46: return 11;
    }
    return -1;
}
Just some minor changes:

Код:
// stock GetWeaponSlotID(const weaponid)
stock GetWeaponSlot(const weaponid)
{
   switch(weaponid)
   {
      case 0,1: return 0;
      case 2 .. 9: return 1;
      case 10 .. 15: return 10;
      case 16 .. 18: return 8;
      case 22 .. 24: return 2;
      case 25 .. 27: return 3;
      case 28,29,32: return 4;
      case 30,31: return 5;
      case 33,34: return 6;
      case 35 .. 38: return 7;
      case 39: return 8;
      case 40: return 12;
      case 41 .. 43: return 9;
      case 44 .. 46: return 11;
   }

   return -1;
}
Reply

Quote:
Originally Posted by Lokii
Посмотреть сообщение
Get weapon slot

Код:
stock GetWeaponSlot(weaponid)
{
    switch(weaponid)
    {
        case 0,1: return 0;
        case 2,3,4,5,6,7,8,9: return 1;
        case 10,11,12,13,14,15: return 10;
        case 16,17,18: return 8;
        case 22,23,24: return 2;
        case 25,26,27: return 3;
        case 28,29,32: return 4;
        case 30,31: return 5;
        case 33,34: return 6;
        case 35,36,37,38: return 7;
        case 39: return 8;
        case 40: return 12;
        case 41,42,43: return 9;
        case 44,45,46: return 11;
    }
    return -1;
}
example 1:

Код:
CMD:test(playerid, params[])
{
     new x[15];
     format(x, sizeof(x), "Minigun slot: %d",  GetWeaponSlot(38));
     printf(x);
     return 1;
}
example 2:

Код:
CMD:test2(playerid, params[])
{
     new x[23];
     format(x, sizeof(x), "Your weapon slot is: %d",  GetWeaponSlot(GetPlayerWeapon(playerid)));
     printf(x);
     return 1;
}
by: Nexius
PHP код:
static const WSlot[] = {0011111111101010101010888, -1, -1, -122233344554667777812999111111};
CMD:test(playeridparams[]) return printf("Minigun slot: %d"WSlot[38]); 
Reply

Why "CallLocalFunction"? Why not just call the function itself (recursion) or better make a non recursive function from that?
Reply

Quote:
Originally Posted by RoW001
View Post
About that RandomPlayer function you can use this.
Code:
GetRandomPlayer()
{
    new iPlayer = -1, iID = random(GetPlayerPoolSize());
    for(new i = 0; i < GetPlayerPoolSize(); i++){
        if(!IsPlayerConnected(i)) continue;
        if(iID == i){
            iPlayer = i;
        } else {
            CallLocalFunction("GetRandomPlayer", "");
        }
    }
    return iPlayer;
}
Code:
GetRandomPlayer(loop=3)
{
    RandomCase:
    loop--;
    if(loop < 0)return -1;
    new iID = random(GetPlayerPoolSize());
    if(IsPlayerConnected(iID))return iID;
    else goto RandomCase;
}
Reply

Or, with y_iterate/foreach: Iter_Random(Player);
Reply

Код:
new randomplayer = random(GetPlayerPoolSize());
Reply

Quote:
Originally Posted by pabloalber84ban
Посмотреть сообщение
Код:
GetRandomPlayer(loop=3)
{
    RandomCase:
    loop--;
    if(loop < 0)return -1;
    new iID = random(GetPlayerPoolSize());
    if(IsPlayerConnected(iID))return iID;
    else goto RandomCase;
}
It should be like this tho:
PHP код:
new iID randomGetPlayerPoolSize() + 1); 
random returns values between 0 and "max - 1", GetPlayerPoolSize returns the highest player ID in use on the server.

EDIT - @OneDay:
Try to compile it, you'll get a nice error. I tried to give an answer in context, anyway, [HLF]Southclaw mentioned Iter_Random just a few comments above!

I know y_iterate would be the way to go (I'm using it actually) but as pawnoholic said: not many people use YSI. So, you might use something like this:

PHP код:
new bool:g_ConnectedPlayers[MAX_PLAYERS char];
public 
OnPlayerConnect(playerid)
{
    
g_ConnectedPlayers{playerid} = true;
    return 
1;
}
public 
OnPlayerDisconnect(playerid)
{
    
g_ConnectedPlayers{playerid} = false;
    return 
1;
}
GetRandomPlayer()
{
    new 
idx;
    new 
true_list[MAX_PLAYERS];
    for(new 
0GetPlayerPoolSize(); tx++)
    {
        if(!
g_ConnectedPlayers{x}) continue;
        
true_list[idx] = x;
        
idx++;
    }
    if(
idx)
    {
        return 
true_list[random(idx)];
    }
    return 
INVALID_PLAYER_ID;

That's just something I wrote here now, I guess there must be a more efficient way for doing it.
Reply

Stop doing meaningless iterations! Build a list of connected players first then simply randomly choose from that list. Iterating through players then doing a `continue;` if the player isn't connected is possibly the worst way to do it.
Reply

Quote:
Originally Posted by RIDE2DAY
Посмотреть сообщение
It should be like this tho:
PHP код:
new iID randomGetPlayerPoolSize() + 1); 
random returns values between 0 and "max - 1", GetPlayerPoolSize returns the highest player ID in use on the server.
It should be like this tho:

PHP код:
new iID Iter_Random(Player); 
It is the fastest already.
Reply

Quote:
Originally Posted by OneDay
View Post
It should be like this tho:

PHP Code:
new iID Iter_Random(Player); 
It is the fastest already.
Not everyone uses y_iterate (foreach)

My not recursive version:

PHP Code:
ReturnRandomPlayer()
{
    new 
        
lastPlayer GetPlayerPoolSize();
    for (new 
random(lastPlayer 1); lastPlayeri++)
    {
        if (
IsPlayerConnected(i))
        {
            return 
i;
        }
    }
    return -
1;

Reply

Quote:
Originally Posted by pawnoholic
View Post
Not everyone uses y_iterate (foreach)

My not recursive version:

PHP Code:
ReturnRandomPlayer()
{
    new 
        
lastPlayer GetPlayerPoolSize();
    for (new 
random(lastPlayer 1); lastPlayeri++)
    {
        if (
IsPlayerConnected(i))
        {
            return 
i;
        }
    }
    return -
1;

Quote:
Originally Posted by [HLF]Southclaw
View Post
Stop doing meaningless iterations! Build a list of connected players first then simply randomly choose from that list. Iterating through players then doing a `continue;` if the player isn't connected is possibly the worst way to do it.
Again, same mistake: If player ID 990 is online and no one else is then you could actually hang the server for a meaningful amount of time. (Yes I know this is an extreme example but you should always keep these kinds of scenarios in mind and evaluate whether or not they truly affect your program at runtime!)

The main thing to learn from this is: predictability. I can not effectively predict the performance of the function because there's no way to predict how many times that for loop could run. The solution below is predictable and is simply a linear function of the highest possible player ID (MAX_PLAYERS).

Here's the best way to do it without foreach:

pawn Code:
stock GetRandomPlayer() {
    new
        online[MAX_PLAYERS],
        total;

    for(new i, j = GetPlayerPoolSize(); i < j; ++i) {
        if(IsPlayerConnected(i)) {
            online[total++] = i;
        }
    }

    if(total == 0) {
        return INVALID_PLAYER_ID;
    }

    return online[random(total)];
}
The obvious evolution of this method would be to simply store a global list of online players and only update it when a player connects or disconnects - that's effectively how the foreach Player iterator works. This way you don't need to calculate the entire list every time because it already exists.

But since that would be more of a snippet than a pure function, this is the quick and dirty alternative - which doesn't really matter if both usage frequency of the function and the player count is low.

If your server is highly populated AND you are calling this function a LOT then I'd advise looking into either foreach or simply storing a up-to-date global list of players. But for all other use-cases, this is fine.
Reply

strequal Fix

strequal - is a function, which compares string variables and values. Returns non-zero if the strings are equal. Fixed probability of a positive result in one blank line, and negative when it's two.

PHP код:
stock bool:strequal(const string1[], const string2[], bool:ignorecase falselength cellmax)
{
    new
        
s1 string1[0],
        
s2 string2[0];
            
    if ((
s1 == '\0' || s2 == '\0') && (s1 != s2))
        return 
false;
            
    return 
strcmp(string1string2ignorecaselength) == 0;

Example:

PHP код:
main()
{
    new
        
str_1[12] = "Hello World",
        
str_2[12] = "Hello World",
        
bool:inequality strequal(str_1str_2);
    
printf("%i"inequality); //inequality = 1

Reply

Quote:
Originally Posted by GRiMMREAPER
View Post
pawn Code:
#include <Pawn.Regex>

isValidMail(mail) {
    new Regex:r = Regex_New("([a-z0-9._-]{6,30})(@{1})([a-z]+)([.]{1})([a-z]{2,})"),
        RegexMatch:m;
   
    if(Regex_Match(mail, r, m)) {
        return 1;
    }

    return 0;
   
}
[I]: cmenezes@gmail.com
[O]: true

[I]: cmenezes22@gmail.com
[O]: true

[I]: cmenezes2@1333@hotmail.pt
[O]: false (@ is not allowed in emails)

[I]: cmen@gmail.com
[O]: false (most email service providers need you to register with an handle ranging from 6 to 30 characters long)

[I]: c23ddsadmen@gmail.c
[O]: false (domain must be equal or longer than 2 characters)
https://davidcel.is/posts/stop-valid...es-with-regex/
Reply

Just skimmed through the post and pieced a few bits. Thanks for the link.
Reply

PHP Code:
IsPlayerInRangeOfPointEx(playeridFloat:radiusFloat:heightFloat:xFloat:yFloat:z)
{
    new 
Float:pxFloat:pyFloat:pz;
    if(!
IsPlayerConnected(playerid)) return 0;
    
GetPlayerPos(playeridpxpypz);
    if(
floatabs((px-x) + (py-y)) <= radius && floatabs((pz-z)) <= height) return 1;
    return 
0;

Reply

PHP Code:
precent(Float:minFloat:max)
{
    return 
_:(floatabs((min/max)*100));

Reply


Forum Jump:


Users browsing this thread: 17 Guest(s)