Useful Functions

totalVeh = -1 should be totalVeh = 0
Reply

Can someone make this:

CreateExplosionInGangZone
Reply

Quote:
Originally Posted by [HLF]Southclaw
Посмотреть сообщение
Ah okay, it was just a rough example, I forgot about ALS (I need to read up on that again!)
And good point about the 'Ex' I'll remember that
Hooking with y_hook is very simple and efficient.

https://sampforum.blast.hk/showthread.php?tid=241446
https://sampforum.blast.hk/showthread.php?tid=166016

using YSI library

https://sampforum.blast.hk/showthread.php?tid=321092
Reply

_ALS_ is just a convention.

https://sampforum.blast.hk/showthread.php?tid=85907
Reply

Also, y_hooks only works on callbacks.

Basically, the "ALS" system detects whether a function has been redefined by another library so that you can chain systems written by different people. There is no reason why "_ALS_" as a prefix is better than any other, there just needs to be a single consistent one so that different libraries are compatible. So by that measure "_ALS_" is better than any other NOW because it is already in use.

If you did "#undef CreateVehicle" and it hadn't already been overridden, you would be trying to undefine a native, which can't be done. On the other hand, if you did "'#define CreateVehicle" and it has already been overridden you would get a redefinition warning. This method detects both (relatively) gracefully.
Reply

I made my own version of sscanf aka 'UnParams'.
It's slow
It's only test of my practice

pawn Код:
#define isNull(%0) \
                    (%0[0] == 0 || (%0[0] == 1 && %0[1] == 0))

stock
        UnParams(params[],format[],{Float,_}:...)
{
    if(isNull(params)) return 0;
   
    new
        formatPos = 0,
        num = numargs(),
        startPos = 2,
        space = ' ',
        startChar = 0,
        pos = 0
    ;
   
    while((startChar = params[pos]) && startChar == space)
    {
        pos++;
    }
    while(startPos < num)
    {
        switch(format[formatPos])
        {
            case 'd','D':
            {
                new
                    str[35],
                    ch,
                    posParam = pos+1
                ;
                while((ch = params[posParam]) && ch != space)
                {
                    if(ch > '9' || ch < '0')
                    {
                        return 0;
                    }
                    posParam++;
                }
                strmid(str,params,pos,pos + (posParam - pos));
                pos = posParam;
                setarg(startPos,0,strval(str));
                formatPos++;               
            }
            case 's','S':
            {
                new
                    str[128],
                    ch,
                    posParam = pos + 1,
                    index
                ;
               
                while((ch = params[posParam]) && ch != space)
                {
                    posParam++;
                }
                strmid(str,params,pos + (((ch = params[pos]) && ch == space) ? 1 : 0),pos + (posParam - pos));
                for(new p,x = strlen(str);p < x;p++)
                {
                    ch = str[p];
                    setarg(startPos,index,ch);
                    index++;
                }
                pos = posParam;
                formatPos++;
            }
            case 'f','F':
            {
                new
                    str[35],
                    ch,
                    posParam = pos+1,
                    dots
                ;
                while((ch = params[posParam]) && ch != space)
                {
                    if(ch > '9' || ch < '0')
                    {
                        if(ch == '.' && dots < 1) dots++;
                        else return 0;
                    }
                    posParam++;
                }
                strmid(str,params,pos + (((ch = params[pos]) && ch == space) ? 1 : 0),pos + (posParam - pos));
                pos = posParam;
                setarg(startPos,0,_:floatstr(str));
                formatPos++;
            }
        }
        startPos++;
    }
    return 1;
}
Reply

Quote:
Originally Posted by Kaczmi
View Post
I made my own version of sscanf aka 'UnParams'.
It's slow
It's only test of my practice
Nice attempt, though:

pawn Code:
UnParams("1234567890123456789012345678901234567890", "i", var);
Reply

Y_Less, i know, i don't know how to fix

it prints:

2123804658

fixed (uknown format)

pawn Код:
#define isNull(%0) \
                    (%0[0] == 0 || (%0[0] == 1 && %0[1] == 0))

stock
        UnParams(params[],format[],{Float,_}:...)
{
    if(isNull(params)) return 0;
   
    new
        formatPos = 0,
        num = numargs(),
        startPos = 2,
        space = ' ',
        startChar = 0,
        pos = 0
    ;
   
    while((startChar = params[pos]) && startChar == space)
    {
        pos++;
    }
    while(startPos < num)
    {
        switch(format[formatPos])
        {
            case 'd','D','i','I':
            {
                new
                    str[35],
                    ch,
                    posParam = pos+1
                ;
                while((ch = params[posParam]) && ch != space)
                {
                    if(ch > '9' || ch < '0')
                    {
                        return 0;
                    }
                    posParam++;
                }
                strmid(str,params,pos,pos + (posParam - pos));
                pos = posParam;
                setarg(startPos,0,strval(str));
                formatPos++;               
            }
            case 's','S':
            {
                new
                    str[128],
                    ch,
                    posParam = pos + 1,
                    index
                ;
               
                while((ch = params[posParam]) && ch != space)
                {
                    posParam++;
                }
                strmid(str,params,pos + (((ch = params[pos]) && ch == space) ? 1 : 0),pos + (posParam - pos));
                for(new p,x = strlen(str);p < x;p++)
                {
                    ch = str[p];
                    setarg(startPos,index,ch);
                    index++;
                }
                pos = posParam;
                formatPos++;
            }
            case 'f','F':
            {
                new
                    str[35],
                    ch,
                    posParam = pos+1,
                    dots
                ;
                while((ch = params[posParam]) && ch != space)
                {
                    if(ch > '9' || ch < '0')
                    {
                        if(ch == '.' && dots < 1) dots++;
                        else return 0;
                    }
                    posParam++;
                }
                strmid(str,params,pos + (((ch = params[pos]) && ch == space) ? 1 : 0),pos + (posParam - pos));
                pos = posParam;
                setarg(startPos,0,_:floatstr(str));
                formatPos++;
            }
            default: return 0;
        }
        startPos++;
    }
    return 1;
}
Reply

Actually, that wasn't even what I was getting at. strval used to crash on massive numbers (maybe it doesn't now, not sure), and the number I had there is longer that 35 characters, thus will give a buffer overflow (though you don't actually need a buffer).
Reply

strreplace - Replace occurrences of the search string with the replacement string.

You can see a demo & test the function here.

pawn Код:
/*
 * strreplace - Replace occurrences of the search string with the replacement string.
 *
 * Supports both packed and unpacked strings.
 *
 * Parameters:
 *   string[] - The string to perform the replacing in.
 *   search[] - The string to look for.
 *   replacement[] - The string to put instead of "search".
 *   ignorecase - Whether the search for "search" should be case-insensitive. Defaults to false.
 *   pos - The position to start at. Defaults to 0 (the beginning).
 *   limit - Limit the number of replacements. Defaults to -1 (no limit).
 *   maxlength - The size of "string". Defaults to sizeof(string), which almost always is what you want.
 *
 * Returns:
 *   The number of replacements that were made.
 */

stock strreplace(string[], const search[], const replacement[], bool:ignorecase = false, pos = 0, limit = -1, maxlength = sizeof(string)) {
    // No need to do anything if the limit is 0.
    if (limit == 0)
        return 0;
   
    new
             sublen = strlen(search),
             replen = strlen(replacement),
        bool:packed = ispacked(string),
             maxlen = maxlength,
             len = strlen(string),
             count = 0
    ;
   
   
    // "maxlen" holds the max string length (not to be confused with "maxlength", which holds the max. array size).
    // Since packed strings hold 4 characters per array slot, we multiply "maxlen" by 4.
    if (packed)
        maxlen *= 4;
   
    // If the length of the substring is 0, we have nothing to look for..
    if (!sublen)
        return 0;
   
    // In this line we both assign the return value from "strfind" to "pos" then check if it's -1.
    while (-1 != (pos = strfind(string, search, ignorecase, pos))) {
        // Delete the string we found
        strdel(string, pos, pos + sublen);
       
        len -= sublen;
       
        // If there's anything to put as replacement, insert it. Make sure there's enough room first.
        if (replen && len + replen < maxlen) {
            strins(string, replacement, pos, maxlength);
           
            pos += replen;
            len += replen;
        }
       
        // Is there a limit of number of replacements, if so, did we break it?
        if (limit != -1 && ++count >= limit)
            break;
    }
   
    return count;
}
Examples:
pawn Код:
new string[200];

// Simple replacement
string = "You can't compare apples and oranges.";
strreplace(string, "apples", "oranges");
print(string);

// Case-insensitive replace
string = "LoremLoremLoremLorem ipsum dolor sit amet, consectetur adipiscing elit.";
strreplace(string, "lorem", "LOREM", .ignorecase = true);
strreplace(string, "DOLOR", "dooloor", .ignorecase = true);
print(string);

// Using an empty replacement string
string = "1111122222333334444455555";
strreplace(string, "2", "");
print(string);

// Using the "limit" argument
string = "bbbbbbbbbb";
strreplace(string, "b", "a", .limit = 5);
print(string);

// Using the "pos" argument
string = "---bbbbbbbbbb---";
strreplace(string, "b", "a", .pos = 5);
print(string);
Reply

Thanks Slice!
Reply

Damn, thank you for that. (@Slice). Works perfect, and it's gonna be very usefull for my gamemode : ).
Just tested it, and it worked like.... a script that works good.

pawn Код:
main()
{
    new string[100];
    string = "* Kevin the noob is dumb *";
    printf("%s", string);
    strreplace(string, "Kevin", "Kwarde");
    strreplace(string, "*", ">>", .limit = 1);
    strreplace(string, "*", "<<", .pos = 1);
    strreplace(string, "dumb", "just a regular scripter");
    strreplace(string, "noob", "PAWN scripter");
    printf("%s", string);
    return 1;
}

/*
** Output **

[12:15:24] * Kevin the noob is dumb *
[12:15:24] >> Kwarde the PAWN scripter is just a regular scripter <<

** End Of Output **
*/
A bit of a dumb string, but it's nice to see how it works : )
Reply

strDelete(szStr[], ...) ─ Deletes sub-strings from a string in a very neat and fast way:
pawn Код:
stock strDelete(szStr[], ...) {
    new
        iStart,
        iAddr,
        iLen,
        iPos
    ;
    #emit ADDR.PRI      szStr
    #emit ADD.C         4
    #emit STOR.S.PRI    iStart
   
    for(new iEnd = iStart + ((numargs() - 1) << 2); iEnd != iStart; iStart += 4) {
        #emit LOAD.S.PRI    iStart
        #emit LOAD.I
        #emit STOR.S.PRI    iAddr
       
        #emit PUSH.S        iAddr
        #emit PUSH.C        4
        #emit SYSREQ.C      strlen
        #emit INC.PRI
        #emit STOR.S.PRI    iLen
        #emit STACK         8
       
    LOOP:
        #emit PUSH.C        0
        #emit PUSH.C        true
        #emit PUSH.S        iAddr
        #emit PUSH.ADR      szStr
        #emit PUSH.C        16
        #emit SYSREQ.C      strfind
        #emit STACK         20
        #emit STOR.S.PRI    iPos
           
        if(iPos != -1) {
            #emit LOAD.S.PRI    iPos
            #emit LOAD.S.ALT    iLen
            #emit ADD
            #emit DEC.PRI
            #emit PUSH.PRI
            #emit PUSH.S        iPos
            #emit PUSH.ADR      szStr
            #emit PUSH.C        12
            #emit SYSREQ.C      strdel
            #emit STACK         16

            #emit JUMP          LOOP
        }
    }
    return 1;
}
Example:
pawn Код:
new string[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
strDelete(string, "ipsum", "sit", ",", "consectetur", "elit");
print(string); // Prints: "Lorem  dolor  amet  adipiscing ."
Reply

My version of strDel

pawn Code:
strDel(string[],...)
{
    new
        num = numargs();
   
    for(new i=1;i<num;i++)
    {
        // GetString
        new str[25],a,b;
        while(!false)
        {
            b = getarg(i,a);
            if(b == 0) break;
            str[a] = b;
            a++;
        }
        //
        new pos;
        while((pos = strfind(string,str,true)) != -1)
        {
            strdel(string,pos,pos+strlen(str));
        }
    }
    return true;
}
Reply

Quote:
Originally Posted by Jack_Leslie
Посмотреть сообщение
I've never seen this, so pardon me if it's already been posted:

Converting a price number (e.g. "$1000") into a price string (e.g. "$1,000"):

How this works: When you format a string or use SendClientMessageEx, you normally use "$%d" for a price. With this stock, you just use "%s" and it will convert it into currency format.

Example:
pawn Код:
format(string, sizeof(string), "This property is for sale!~n~Price: %s", ConvertPrice(HouseInfo[idx][Price]))");
Stock:
pawn Код:
stock ConvertPrice(price)
{
    new pricestring[32];
    new j = valstr(pricestring,price);
    while(j >= 4) { j -= 3; strins(pricestring,",",j); }
    strins(pricestring,"$",0);
    return pricestring;
}
That functions looks similar to the /sellhouse command in the SA:RP script...

pawn Код:
if(strcmp(tmp,"confirm",true) == 0)
                {
                    new pricestring[32];
                    new price = PlayerInfo[playerid][hValue]/4;
                    new j = valstr(pricestring,price);
                    while(j >= 4) { j -= 3; strins(pricestring,",",j); }
                    strins(pricestring,"$",0);
                   
                    GiveMoney(playerid, price);
                    PlayerPlaySound(playerid, Songs[1][0], 0.0, 0.0, 0.0);
                    SetTimerEx("StopSongTimer", 5000, false, "i", playerid);
                    format(string, sizeof(string), "Congratulations, You have sold your property and received 25 percent of the value, %s.", pricestring);
                    SendClientMessage(playerid, COLOR_YELLOW, string);
                    format(string, sizeof(string), "~w~Congratulations~n~ You have sold your property for ~n~~g~%s", pricestring);
                    GameTextForPlayer(playerid, string, 10000, 3);
                    RejectHouse(playerid);
                    OnPlayerSave(playerid);
                }
Reply

Sexy code SLice x;P

Quote:
Originally Posted by RyDeR`
Посмотреть сообщение
Yet another version of quickSort implemented (from C++) to PAWN. I tested serveral times and it worked flawless (even a little bit faster than existing versions).

Output:
Код:
-564
-541
-541
0
3
3
12
54
55
66
689
1554
1656
5468484
WELL pretty cool job , but
Lets take an exaple : we try that code to sort KILLS and get name along with it from a DB or smthng ;and if 2
player has same kills
It will mess won't it ?
guess it will Give Player Name
same for both Kills at that particular rows ?
Reply

Quote:
Originally Posted by Niko_boy
Посмотреть сообщение
Sexy code SLice x;P



WELL pretty cool job , but
Lets take an exaple : we try that code to sort KILLS and get name along with it from a DB or smthng ;and if 2
player has same kills
It will mess won't it ?
guess it will Give Player Name
same for both Kills at that particular rows ?
Slice just released an include which makes it easier and it's pretty much documented so I recommend checking that out. Click here.
Reply

Quote:
Originally Posted by RyDeR`
Посмотреть сообщение
Slice just released an include which makes it easier and it's pretty much documented so I recommend checking that out. Click here.
Yeah Just checked it out =)
Reply

Quote:
Originally Posted by Slice
Посмотреть сообщение
Unarmed (0) and brass knuckles (1) returns WEAPONSLOT_FIST (0).
Golf club (2) and nightstick (3) returns WEAPONSLOT_MELEE (1).
Everything's clear now. Thank you.
Reply

Create a TextDraw box. This is about as accurate as I could get it.

If x1/2 or y1/2 is negative, the values will be relative to the bottom-right corner. For example, this will create a box in the middle of the screen:

pawn Код:
new Text:td = TextDrawCreateBox(0x00000099, 100.0, 100.0, -100.0, -100.0);

TextDrawShowForAll(td);
pawn Код:
stock Text:TextDrawCreateBox(color, Float:x1, Float:y1, Float:x2, Float:y2) {
    new Text:td, Float:height;
   
    // Coords less than 0 will be relative to the bottom-right corner
    if (x1 < 0.0) x1 += 640.0;
    if (x2 < 0.0) x2 += 640.0;
    if (y1 < 0.0) y1 += 480.0;
    if (y2 < 0.0) y2 += 480.0;
   
    // Make sure the box is from top/left towards right/bottom
    // If not, swap the variables (XOR swap).
    if (x1 > x2) x1 ^= x2, x2 ^= x1, x1 ^= x2;
    if (y1 > y2) y1 ^= y2, y2 ^= y1, y1 ^= y2;
   
    height = y2 - y1;
   
    td = TextDrawCreate(x1 * 1.003, y1 * 0.941, "_");
   
    TextDrawUseBox(td, true);
    TextDrawSetShadow(td, 0);
    TextDrawAlignment(td, 1);
    TextDrawSetOutline(td, 0);
    TextDrawBoxColor(td, color);
    TextDrawColor(td, 0);
    TextDrawBackgroundColor(td, 0);
    TextDrawTextSize(td, (x2 - 4.7) * 1.0025, 0.0);
    TextDrawLetterSize(td, 0.0, height * 0.1045 - 0.55);
   
    return td;
}
Reply


Forum Jump:


Users browsing this thread: 29 Guest(s)