Useful Functions

True, I forgot that. Editing my post now.

pawn Код:
stock GetBiggestArrayNumber(array[], len = sizeof(array))
{
    new
        biggest = cellmin
    ;
    for(new i ; i != len; ++i)
    {
        if(array[i] > biggest)
        {
            biggest = array[i];
        }
    }
    return biggest;
}

stock GetSmallestArrayNumber(array[], len = sizeof(array))
{
    new
        smallest = cellmax
    ;
    for(new i ; i != len; ++i)
    {
        if(array[i] < smallest)
        {
            smallest = array[i];
        }
    }
    return smallest;
}
Reply

Changed.
Reply

Use "cellmin", not "-cellmax", they are actually subtly different.
Reply

Meh.......

SetPlayerMaxHealth(playerid, Float:maxhealth);
>> returns No specific value I guess...

pawn Code:
new Float:MaxHealth[MAX_PLAYERS];

stock SetPlayerMaxHealth(playerid, Float:maxhealth)
{
    new name[24]; GetPlayerName(playerid,name,24);
    MaxHealth[playerid] = maxhealth;
    printf("%s (%d) Has A New Max Health Which Is %f.",name,playerid,maxhealth);
    return 1;
}
GetPlayerMaxHealth(playerid, &Float:maxhealth);

>> returns the max health set.
pawn Code:
new Float:MaxHealth[MAX_PLAYERS];

stock GetPlayerMaxHealth(playerid, &Float:maxhealth)
{
    new name[24]; GetPlayerName(playerid,name,24);
    printf("%s (%d) Max Health Is %f",name,playerid);
    return MaxHealth[playerid];
}
Not tested, may test..
Reply

That's not making shorter. That's making the code more "ugly".
Reply

pawn Код:
stock CompassCorners(Float:X, Float:Y, Float:TargetX, Float:TargetY) return (X < TargetX) ? (Y < TargetY ? 1 : 2) : (Y < TargetY ? 3 : 4);
now that is better, lol. I like this "method" and the "method" RyDeR` posted
Reply

I don't see how Kwarde was making it ""ugly"" in any way. Anyways here's how it's done:
pawn Код:
stock CompassCorners(Float:a,Float:b,Float:c,Float:d)return a<c?b<d?1:2:b<d?3:4;
Perfect, isn't it?! Exactly 80 chars.
Reply

I don't understand why you guys repost the corrected code by me over and over with different ways of spacing, tabbing. What's the point of this?
For me the code without { } looks ugly. That's how I am. I don't care how anyone else is feeling about this.
Reply

I know why mine's "ugly". I'm ugly :')
And slice, you owned us :') Or wait... Sometimes I see functions without 'stock'
pawn Код:
CompassCorners(Float:a,Float:b,Float:c,Float:d)return a<c?b<d?1:2:b<d?3:4;
:P - However,
I like codes more without {} brackets if it's just one single line
Reply

Quote:
Originally Posted by RyDeR`
Посмотреть сообщение
I don't understand why you guys repost the corrected code by me over and over with different ways of spacing, tabbing. What's the point of this?
For me the code without { } looks ugly. That's how I am. I don't care how anyone else is feeling about this.
How does the appearance of code have any relevance to coding, at all?

Tab-spacing is very useful for reading your own code and organizing it, but this isn't a fashion contest, it's quite the inverse.

__________________________________________________ _________________________________________

Count the amount of control characters in a string.
Use this function to count the amount of control characters found in a string (null-terminators exempt), by specifying the character type and the string name.

Usage: countControlCharacters('r', "\rfffff\r");

Returns amount of characters found with the specified type.

pawn Код:
stock countControlCharacters(character, inSz[]) {
    new
        ccCount;

    switch(character) {
        case 'n': {
            for(new it = 0; it < strlen(inSz); it++) {
                if(inSz[it] == '\n') ccCount++;
            }
        }
        case 'r': {
            for(new it = 0; it < strlen(inSz); it++) {
                if(inSz[it] == '\r') ccCount++;
            }
        }
        case 't': {
            for(new it = 0; it < strlen(inSz); it++) {
                if(inSz[it] == '\t') ccCount++;
            }
        }
        default: {
            print("Critical error: Type undefined for countControlCharacters.");
        }
    }


    return ccCount;
}
I wouldn't really call this useful, but I wanted to release some kind of generic function.
Reply

Patch the dialog crash exploit! (String placeholders are filtered in SA:MP's chatbox, which is not the case in dialogs - it's been the cause of many server attacks). Insert this directly under OnDialogResponse.

Код:
if(!(inputtext[0] == 0 || (inputtext[0] == 1 && inputtext[1] == 0))) for(new strPos; inputtext[strPos] > 0; strPos++) if(inputtext[strPos] == '%') inputtext[strPos] = ' ';
Reply

Crap! I was just making a post on how using strfind would be faster.

Anyways, benchmarking:
Код:
 Bench for Looping the string: executes, by average, 159 times/ms (159164 times, 1000 ms).
 Bench for Using strfind: executes, by average, 825 times/ms (825567 times, 1000 ms).
Edit: Calgon's countControlCharacters function gave me an idea, so I made these:

Usage:
pawn Код:
CountChars( haystack[], needless[] ); // Counts each char in the needless string and returns the number of matches.
CountMatches( haystack[](, needle[], ...) ); // Counts the string(s) passed after the haystack - it's possible to match up to 62 strings.
Code:
You can probably tell I've been doing too much JavaScript lately by looking at the for-loops. lol.
pawn Код:
stock CountChars( const szString[ ], const szChars[ ] )
{
    new iCount = 0, iPos;
   
    for ( new szSearchChar[ 2 ], i = 0; ( szSearchChar[ 0 ] = szChars[ i ] ); i++ )
    {
        iPos = -1;
       
        while ( ( iPos = strfind( szString, szSearchChar, false, ++iPos ) ) != -1 )
            ++iCount;
    }
   
    return iCount;
}

stock CountMatches( const szString[ ], bool:bIgnoreCase = false, ... )
{
    new iMatches, szBuffer[ 64 ], i, iArgs, c, j, iPos;
   
    iMatches = 0;
    iArgs = numargs( );
   
    for ( i = 2; i < iArgs; i++ )
    {
        for ( j = 0; ( c = getarg( i, j ) ); j++ )
            szBuffer[ j ] = c;
       
        szBuffer[ j + 1 ] = 0;
       
        iPos = -1;
       
        while ( ( iPos = strfind( szString, szBuffer, bIgnoreCase, ++iPos ) ) != -1 )
            ++iMatches;
    }
   
    return iMatches;
}

public OnFilterScriptInit( )
{
    printf( "%d", CountChars( "I\nLike\nNew\nLines\n:D.\t\t\t\ttabs!", "\n\t" ) );
    printf( "%d", CountMatches( "I like to repeat myself. I like to repeat myself. I like to repeat myself.", false, "I", "repeat" ) );
   
    new iMatches = CountMatches( "Fuckin.. What the fuckin fuck?! Who the fuck fucked this fucking...?? How did you two fucking fucks...?! FUCK!!", false, "fuck" );
   
    if ( iMatches > 5 )
        printf( "Enough cursing!!" );
}
Reply

Quote:
Originally Posted by ******
Посмотреть сообщение
A strreplace would be very handy.
pawn Код:
stock strreplace2(string[], const find[], const replace[], bool:ignorecase=false, count=cellmax, maxlength=sizeof(string))
{
    if(isnull(find) || isnull(string)) return 0;
    new matches;
    for(new idx, flen = strlen(find), rlen = strlen(replace), pos = strfind(string, find, ignorecase); pos != -1 && idx < maxlength && matches < count; pos = strfind(string, find, ignorecase, idx))
    {
        strdel(string, pos, pos + flen);
        if(rlen) strins(string, replace, pos, maxlength);
        idx = pos + rlen;
        matches++;
    }
    return matches;
}
Not by me though.
Reply

haha, I'd never thought strfind would be so damn fast. Pays to try these things I guess
Reply

Quote:
Originally Posted by Brian.
Посмотреть сообщение
haha, I'd never thought strfind would be so damn fast. Pays to try these things I guess
The reason it's so fast is it's a C-function. When doing string manipulation in PAWN, it's best to use the native string functions as much as possible.

Anyways, I made this just now:

GetParam
Note: I have not fully tested this - only like 80% of the possible different inputs.

Am I the only one pissed off at strtok? Not sure why but it just annoys me.

Anyways, I made this function as a replacement. It's slightly faster than strtok, and easier to use.

Usage:
pawn Код:
GetParam( string[], param_num );
string is the string you want to look for params in, and param_num is the index of the param you want, starting at 1.
The function will seamlessly trim the string and return it.

Example:
pawn Код:
new params[] = "   I would  like to \t\t\nhave\n   50    bags    of   cheetos.\r\n";
   
    printf( "1: \"%s\"", GetParam( params, 1 ) ); // Prints "I"
    printf( "2: \"%s\"", GetParam( params, 2 ) ); // Prints "would"
    printf( "3: \"%s\"", GetParam( params, 3 ) ); // Prints "like"
    printf( "4: \"%s\"", GetParam( params, 4 ) ); // Prints "to"
    printf( "5: \"%s\"", GetParam( params, 5 ) ); // Prints "have"
    printf( "6: \"%s\"", GetParam( params, 6 ) ); // Prints "50"
    printf( "7: \"%s\"", GetParam( params, 7 ) ); // Prints "bags"
    printf( "8: \"%s\"", GetParam( params, 8 ) ); // Prints "of"
    printf( "9: \"%s\"", GetParam( params, 9 ) ); // Prints "cheetos."
Code:
pawn Код:
stock GetParam( const szString[ ], iParam )
{
    new iSearchPos, iPos, iHoles, szReturn[ 128 ], iFoundParam = -1;
   
    if ( szString[ 0 ] <= 1 ) // Treat \1 as a null character for ZCMD/YCMD compatibility.
        return szReturn; // If the string is empty there's no point in looking for stuff.
   
    iPos = -1;
   
    while ( 2 <= szString[ ++iPos ] <= ' ' ) {} // Trim the beginning of the string.
   
    if ( --iParam == 0 ) // Wether or not we're looking for the first parameter.
    {
       
       
        if (
               ( iSearchPos = strfind( szString, " ", _, iPos ) ) != -1 // Search for a space/tab
            || ( iSearchPos = strfind( szString, "\t", _, iPos ) ) != -1
        )
            strcat( szReturn, szString[ iPos ], iSearchPos + 1 - iPos ); // Put the found part into the return.
        else
            strcat( szReturn, szString[ iPos ] ); // Put the whole thing (except for the first tabs/spaces, if any) into the return.
    }
    else
    {
        while (
               ( iSearchPos = strfind( szString, " ", _, iPos ) ) != -1 // Search for a space/tab
            || ( iSearchPos = strfind( szString, "\t", _, iPos ) ) != -1
        )
        {
back_in_action:
            iPos = iSearchPos;
           
            while ( 2 <= szString[ ++iPos ] <= ' ' ) {} // Skip any whitespace.
           
            if ( iFoundParam != -1 ) // If the previous iteration found a param..
            {
                strcat( szReturn, szString[ iFoundParam ], iPos - iFoundParam ); // Put it into the return string.
               
                iFoundParam = -1;
               
                break; // Then BREAK YOSELF.
            }
           
            if ( ++iHoles == iParam ) // If this current "hole" is in front of the param we're looking for..
                iFoundParam = iPos; // ..let the script know that.
        }
       
        if ( iFoundParam != -1 ) // If a param was found in the last iteration.. (end of the string)
        {
            iSearchPos = strlen( szString ); // Set the next position to the end of the string.
           
            goto back_in_action;
        }
    }
   
    if ( szReturn[ 0 ] )
    {
        // Trim any whitespace on the right side.
        for ( iPos = strlen( szReturn ) - 1; iPos >= 0 && szReturn[ iPos ] <= ' '; iPos-- )
            szReturn[ iPos ] = 0;
    }
   
    return szReturn;
}
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
pawn Код:
stock GetParam( const szString[ ], iParam )
{
    new iSearchPos, iPos, iHoles, szReturn[ 128 ], iFoundParam = -1;
   
    if ( szString[ 0 ] <= 1 ) // Treat \1 as a null character for ZCMD/YCMD compatibility.
        return szReturn; // If the string is empty there's no point in looking for stuff.
   
    iPos = -1;
   
    while ( 2 <= szString[ ++iPos ] <= ' ' ) {} // Trim the beginning of the string.
   
    if ( --iParam == 0 ) // Wether or not we're looking for the first parameter.
    {
       
       
        if (
               ( iSearchPos = strfind( szString, " ", _, iPos ) ) != -1 // Search for a space/tab
            || ( iSearchPos = strfind( szString, "\t", _, iPos ) ) != -1
        )
            strcat( szReturn, szString[ iPos ], iSearchPos + 1 - iPos ); // Put the found part into the return.
        else
            strcat( szReturn, szString[ iPos ] ); // Put the whole thing (except for the first tabs/spaces, if any) into the return.
    }
    else
    {
        while (
               ( iSearchPos = strfind( szString, " ", _, iPos ) ) != -1 // Search for a space/tab
            || ( iSearchPos = strfind( szString, "\t", _, iPos ) ) != -1
        )
        {
back_in_action:
            iPos = iSearchPos;
           
            while ( 2 <= szString[ ++iPos ] <= ' ' ) {} // Skip any whitespace.
           
            if ( iFoundParam != -1 ) // If the previous iteration found a param..
            {
                strcat( szReturn, szString[ iFoundParam ], iPos - iFoundParam ); // Put it into the return string.
               
                iFoundParam = -1;
               
                break; // Then BREAK YOSELF.
            }
           
            if ( ++iHoles == iParam ) // If this current "hole" is in front of the param we're looking for..
                iFoundParam = iPos; // ..let the script know that.
        }
       
        if ( iFoundParam != -1 ) // If a param was found in the last iteration.. (end of the string)
        {
            iSearchPos = strlen( szString ); // Set the next position to the end of the string.
           
            goto back_in_action;
        }
    }
   
    if ( szReturn[ 0 ] )
    {
        // Trim any whitespace on the right side.
        for ( iPos = strlen( szReturn ) - 1; iPos >= 0 && szReturn[ iPos ] <= ' '; iPos-- )
            szReturn[ iPos ] = 0;
    }
   
    return szReturn;
}
Is it really that wise to use a goto? I've seen some really strange behaviour when using goto structures before in PAWN.
Reply

You have to be really careful when using it. Goto is a dinosaur now and some languages don't support it anymore for a reason.
Reply

I use goto sometimes to jump back into loops. I have extensively tested its stability and never found any issues as long as I use it carefully. In assembly, a while-loop ultimately uses the same asm opcodes to loop as goto does.
I'm going to hide now, because I have a feeling someone with a HL2-style logo won't like my using goto!
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
I use goto sometimes to jump back into loops. I have extensively tested its stability and never found any issues as long as I use it carefully. In assembly, a while-loop ultimately uses the same asm opcodes to loop as goto does.
Fair enough if you've performed some kind of research and found that out.
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
I use goto sometimes to jump back into loops. I have extensively tested its stability and never found any issues as long as I use it carefully. In assembly, a while-loop ultimately uses the same asm opcodes to loop as goto does.
I'm going to hide now, because I have a feeling someone with a HL2-style logo won't like my using goto!
Yepp. Goto is excellent but you need to be aware of what you're doing if you're going to use it.
Reply


Forum Jump:


Users browsing this thread: 10 Guest(s)