Multiple parameters
#1

So I want to make somehow mine format function, who can give me more elasticity. But how I can make with multiple params?

for example
format(bla, sizeof(bla), "%s%s%s%s%i%s", gfdgf, dfgfdg, fdgdfg, dfgdfg, 10, fdgf)
but I want to make function like

public blah(ewrw, werwe, and here to have as many I can the as array);

I used some random variable name, to show you what I want
Reply
#2

Use forward "ursubjecthere"
Reply
#3

Ummm, how?
Reply
#4

For Example...

PHP код:
forward SpawnProtect(playerid);
public    
SpawnProtect(playerid)
{
    
SetPlayerHealth(playeridFLOAT_INFINITY);
    
AntiSKr[playerid] = random(3);
    switch(
AntiSKr[playerid])
    {
        case 
0:
        {
            
AntiSKa[playerid] = 10*1000// 10 multiplied by 1000 mili-secs = 10 seconds.
            
SendClientMessage(playerid0x8F8F8FFF"[SPAWN]: {FFFFFF}You have spawn protection for 10 seconds.");
        }
        case 
1:
        {
            
AntiSKa[playerid] = 15*1000// 15 multiplied by 1000 mili-secs = 15 seconds.
            
SendClientMessage(playerid0x8F8F8FFF"[SPAWN]: {FFFFFF}You have spawn protection for 15 seconds.");
        }
        case 
2:
        {
            
AntiSKa[playerid] = 20*1000// 20 multiplied by 1000 mili-secs = 20 seconds.
            
SendClientMessage(playerid0x8F8F8FFF"[SPAWN]: {FFFFFF}You have spawn protection for 20 seconds.");
        }
    }
    
AntiSK[playerid] = 1;
    
AntiSKt[playerid] = SetTimerEx("AntiSKfunc"AntiSKa[playerid], false"i"playerid);
    
SendClientMessage(playerid0x8F8F8FFF"[SPAWN]: {FFFFFF}Press key '{781F59}N{FFFFFF}' to end spawn protection.");
    return 
1;

Anti-Spawn Protection By ALiScripter.
Reply
#5

I would look into the va_format function developed by ZeeX and ******.

It's a complex but simple method to approach formatting arguments into a string.

http://pastebin.com/R3ZeiK7L

Example usage:
PHP код:
SendFormattedMessage(playeridcolour, const formatstr[], va_args<>)
{
    new 
format_output[145];
    
va_format(format_outputsizeof(format_output), formatstrva_start<3>);
    return 
SendClientMessage(playeridcolourformat_output);
}

public 
OnPlayerSpawn(playerid)
{
    
SendFormattedMessage(playerid, -1"Your skin ID is %d, you are on team %d and your score is %d."GetPlayerSkin(playerid), GetPlayerTeam(playerid), GetPlayerScore(playerid));
    return 
1;

Reply
#6

Thanks, but actually I want to understand how I can make this without any includes.
I'm just curios how I can do this without any include
Reply
#7

#emit directive

https://sampforum.blast.hk/showthread.php?pid=1608985#pid1608985
https://sampforum.blast.hk/showthread.php?tid=570930
https://sampforum.blast.hk/showthread.php?tid=591705

There are many versions you can find if you search or write your own. If there are 3 static parameters (just like playerid, color and form in the function below) in the function you want to make, the faster method is by Nero_3D:
pawn Код:
SCM(playerid, color, form[], {Float, _}: ...)
{
    #pragma unused form

    static tmp[145];
    new t1 = playerid, t2 = color;
    const n4 = -4, n16 = -16, size = sizeof tmp;

    #emit stack 28
    #emit push.c size
    #emit push.c tmp
    #emit stack n4
    #emit sysreq.c format
    #emit stack n16

    return SendClientMessage(t1, t2, tmp);
}
for more or less static parameters the above will not work.
Reply
#8

Код:
    const n4 = -4, n16 = -16, size = sizeof tmp;

    #emit stack 28
    #emit push.c size
    #emit push.c tmp
    #emit stack n4
    #emit sysreq.c format
    #emit stack n16
ummm, I tried to read about this, but I cant understand nothing from here... I just want a concrete patern that I use in my case. I dont want library, because I want to try it by myself, I want to learn something from this
Reply
#9

Usually I jump around in the stack to avoid loops
But the normal way would to to push the arguments on the stack again
Push the parameters from right to left than the byte count and after that call the function
But that is bascially what y_va did (you will notice if you check out va_printf or va_format)
Quote:
Originally Posted by Threshold
Посмотреть сообщение
There are a lot of comments in y_va so it shouldn't be to difficult
If you need to lookup an emit code go to "Instruction reference" in pawn_implementer_guide.pdf
Reply
#10

It is surely not easy, you need to have a good understanding of how the virtual machine works. I'll give you a sample which will help you to modify it to your needs:
Код:
HOOKED_FUNCTION_NAME(STATIC_PARAMETERS_HERE, {Float, _}: ...)
{
    static str[SIZE_OF_STRING_HERE], args;

    if ((args = numargs()) == NUMBER_OF_STATIC_PARAMETERS_HERE)
    {
        // Call directly the function, it doesn't have arguments to format
        return FUNCTION_NAME(STATIC_PARAMETERS_HERE);
    }

    while (--args > NUMBER_OF_STATIC_PARAMETERS_HERE - 1)
    {
        // Load the address relative to the parameter.

        // pri = [FRM]
        #emit LCTRL 5
        // Add 12 to skip to the parameters.
        #emit ADD.C 12
        // Add the offset to the argument.
        #emit LOAD.alt args
        // alt <<= 2;
        #emit SHL.C.alt 2
        // Add the result.
        #emit ADD
        // Load the address.
        #emit LOAD.I
        // Push.
        #emit PUSH.pri
    }

    // Push the parameters for "format" function (in reverse).

    // format[]
    #emit PUSH.S string
    // len
    #emit PUSH.C SIZE_OF_STRING_HERE
    // output[]
    #emit PUSH.C str

    // Push the number of arguments (stored in address 8) and call native "format"
    #emit LOAD.S.pri 8
    #emit ADD.C 8
    #emit PUSH.pri
    #emit SYSREQ.C format

    // Restore the stack and heap.
    #emit LCTRL 5
    #emit SCTRL 4

    return FUNCTION_NAME(STATIC_PARAMETERS_HERE_EXCEPT_LAST_STRING, str);
}
and because of the sysreq bug, include:
pawn Код:
forward _SYSREQ_fix_();
public _SYSREQ_fix_()
{
    format("", 0, "");
}
so it won't crash the compiler. So basically, you have to change the orange text only (add the static parameters, the number of them and the size of the string). An example now with 2 static parameters (db and query):
Код:
DBResult: db_queryf(DB: db, query[], {Float, _}: ...)
{
    static str[1024], args;

    if ((args = numargs()) == 2)
    {
        return db_query(db, query);
    }

    while (--args > 1)
    {
        #emit LCTRL 5
        #emit ADD.C 12
        #emit LOAD.alt args
        #emit SHL.C.alt 2
        #emit ADD
        #emit LOAD.I
        #emit PUSH.pri
    }

    #emit PUSH.S query
    #emit PUSH.C 1024
    #emit PUSH.C str

    #emit LOAD.S.pri 8
    #emit ADD.C 8
    #emit PUSH.pri
    #emit SYSREQ.C format

    #emit LCTRL 5
    #emit SCTRL 4

    return db_query(db, str);
}
You can hopefully create your own functions with formatting easily. For more related to #emit, read the tutorials and the PAWN Implementer Guide (even though the directive itself is not documented, you can find about opcodes, mnemonics and semantics).
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)