FANDOM


A set of (sometimes) silly macros that make certain YSI coding jobs even easier. Every macro is just one letter that corresponds as near as possible to its function. Although this did start off as a joke (because coding using very short identifiers isn't a good idea in the long run due to the obfuscation involved), several macros (especially D) have turned out to be very useful.

Name Edit

There are multiple definitions of what the name means, as well as alternate versions for different keyboad layouts.

QWERTYUIOP Edit

Quaint Wrappers Enabling Relatively Tearse YSI Usage, Implicitly Optimising Performance

Quaint Wrappers Enabling Relatively Tearse YSI Usage, Instead of Perplexity

AZERTYUIOP Edit

A Zebra Enabling Relatively Tearse YSI Usage, Implicitly Optimising Performance

(Yes, the zebra is real).

Macros Edit

A Edit

  • A is for Armour

Returns a player's current armour without you needing to use an intermediate variable:


printf("%f", A(playerid));


B Edit

  • B is for Bit

Simplifies the usage of y_bits, so instead of needing to learn "Bit_Set" and "Bit_Get", you can just use almost array-like syntax while still reducing memory consumption 32-fold:


new BitArray:arr<100>
B:arr<42> = true;
if (B:arr<10>)
{
    // Do whatever.
}


C Edit

  • C is for Code

This is one of the two macros defined in YSI long-ago. This is the debug code macro, and encloses code you only want when debugging:


#define _DEBUG 1

// Includes.

main()
{
    C:1(foreach(new i : Player) printf("%d", i););
}


Note that because this is VERY old code, you need complete code in the brackets, AND you need to end the line with a semi-colon, hence the "););" at the end. One to end "printf", one to end "C". The number is the debug level (of which there are 7). If "_DEBUG" is greater than, or equal to, that number then the code will be compiled, otherwise it will be entirely left out.

For more information see y_debug. This is similar to the "P:C" macro documented there, but with the ability to specify the debug level at which the code appears.

D Edit

  • D is for Dialog

This wraps several bits of code from y_text, y_dialog, and y_inline all at once:


D:0(playerid, DIALOG_STYLE_PASSWORD, $LOGIN_TITLE, $LOGIN_TEXT, $BUTTON_1, $BUTTON_2)
{
    // Parse the result here.
}


This is similar to writing this:


inline Func0(playerid0, dialogid0, response0, listitem0, inputtext0[])
{
    // Parse the result here.
}

Text_ShowDialog(playerid, DIALOG_STYLE_PASSWORD, using inline Func0, $LOGIN_TITLE, $LOGIN_TEXT, $BUTTON_1, $BUTTON_2);


The number after "D" (here "0") is the LOCAL dialog ID. They are local in that they are bound by scoping rules. You can't have two dialogs with the same number in the same scope, but you CAN have two with the same number shown from different functions. The number (as shown above) is a suffix for the standard dialog variables so that you can do things like this without bugs:


if (!Registered(playerid))
{
    D:0(playerid, DIALOG_STYLE_PASSWORD, $REGISTER_TITLE, $REGISTER_TEXT, $BUTTON_1, $BUTTON_2)
    {
        // A DIFFERENT dialog 0 (different scope).
    }
}
else
{
    D:0(playerid, DIALOG_STYLE_PASSWORD, $LOGIN_TITLE, $LOGIN_TEXT, $BUTTON_1, $BUTTON_2)
    {
        // Parse the result here.
        D:1(playerid, DIALOG_STYLE_PASSWORD, $RETRY_TITLE, $RETRY_TEXT, $BUTTON_1, $BUTTON_2)
        {
            // Parse the result here without clashes
        }
        
    }
}


I'm not going to explain this one too deeply, but it should be pretty clear if you are familiar with y_text, y_dialogs, and y_inline (and despite the fact that this was meant to be a joke, it's actually quite useful).

The ID is now optional if you only have one dialog in scope:


if (isnull(reason))
{
    // No reason given.
    D(pid, DIALOG_STYLE_INPUT, $COMM_NO_REASON, $COMM_BAN_REASON, $DIALOG_OK, $DIALOG_CANCEL)
    {
        #pragma unused playerid, dialogid, listitem
        if (response)
        {
            Cmd_TryBan(pid, banid, inputtext);
        }
        return 1;
    }
}


E Edit

  • E is for <unused>


F Edit

  • F is for function


F:Func(params)
{
}


Becomes:


forward Func(params);

public Func(params)
{
}


G Edit

  • G is for Group

This is a combination of "Group_Create" and "GROUP_ADD" - both of which are documented in the y_groups tutorial. This enables you to quickly create a group and set things to only that group:


new Group:g = G("some group")
{
    @YCMD:hi;
}


This is equivalent to:


new Group:g = Group_Create("some group");
GROUP_ADD<g>
{
    @YCMD:hi;
}


H Edit

  • H is for Health

See "A":


printf("%f", H(playerid));


I Edit

  • I is for Iterator

This is a wrapper for by far the most common type of loop in SA:MP scripting:


I // foreach (new i : Player)
{
    printf("Current player: %d", i);
}


J Edit

  • J is for Jagged

This adds custom syntax for creating jagged arrays. See the y_jaggedarray topic for more details:


new J:arr[10]<1, 1, 2, 3, 5, 8, 13, 21, 34, 55>;


K Edit

  • K is for <unused>


L Edit

  • L is for Loop

This is for possibly the second most common loop in SA:MP:


L(j, 42) // for (new j = 0; j != 42; j++)
{
}


M Edit

  • M is for <unused>


N Edit

  • N is for Name

See "A" and "H":


printf("%s", N(playerid));


O Edit

  • O is for Object

Possibly the simplest macro. This just creates a normal object, or a dynamic object if a streamer exists:


O(1337, 100.0, 123.0, 6.0, 0.0, 0.0, 0.0);


P Edit

  • P is for Print

This is the other YSI macro. It is similar to "C" in that it is a debugging tool not included if "_DEBUG" is a lower value than specified. This is the reason why compiling YSI with "#define _DEBUG 7" spams the console endlessly:


#define _DEBUG 7

// Includes.

main()
{
    P:1("%d", 42);
}


The parameters are the same as "printf". Interestingly "P:C" is a synonym for "C:1" for consistency (I may remove "C" since even I don't use it).

For more information see y_debug.

Q Edit

  • Q is for QWERTYUIOP

Just try it:


main()
{
    Q!
}


R Edit

  • R is for <unused>


S Edit

  • S is for Sending messages

This is a wrapper for "Text_Send", and that's it (as "Text_Send" is already a very powerful macro):


S($SOME_TEXT, params, go, here);
S($DISPLAY_DATA, N(playerid), H(playerid), A(playerid));


T Edit

  • T is for <unused>


U Edit

  • U is for <unused>


V Edit

  • V is for Vehicle

This is a wrapper for "CreateVehicle", and also adds a "Vehicle" iterator to which all "V" vehicles are added:


foreach (new v : Vehicle)
{
    // Do something with all vehicles using "V" instead of "CreateVehicle".
}


W Edit

  • W is for Wait

Yes, this is the old "Sleep" code, BUT WITHOUT HANGING THE SERVER! This uses y_inline and timers to defer the execution of part of a function (with some restrictions):


MyFunc(a)
{
    printf("hi %d", a);
    W(10000);
    printf("there %d", a);
    return 1;
}


That will print "hi <n>", wait 10 seconds, then print "there <n>". I say there are some restrictions, these are the standard y_inline restrictions:

Firstly, this will NOT defer the rest of the stack:


Func0()
{
    printf("start");
    MyFunc(42);
    printf("end");
    return 1;
}


This will print:


start
hi 42
end
there 42


ONLY the remainder of the CURRENT function will be deferred because copying the whole stack and heap is just too hard. You can detect when a function has been deferred by checking the return value is "cellmin":


Func0()
{
    printf("start");
    if (MyFunc(42) == cellmin)
    {
        printf("defer");
    }
    else
    {
        printf("end");
    }
    return 1;
}


This will print:


start
hi 42
defer
there 42


Speaking of copying the stack and heap, you can't pass strings to your function. This will not work:


MyFunc(a, string:s[])
{
    printf("hi %d", a);
    W(10000);
    printf("there %s", s);
    return 1;
}


That will save the address that is "s", but by the time the second half of the function is called the memory it points to will have changed. You CAN, however, do this:


MyFunc(a, string:_s[])
{
    new s[YSI_MAX_STRING];
    strcpy(s, _s);
    printf("hi %d", a);
    W(10000);
    printf("there %s", s);
    return 1;
}


That will store a copy of the string locally in the function.

Also note that I'm VERY happy that I wrote this macro with no modifications to y_inline AT ALL, which I believe just goes to show the power of YSI!


X Edit

  • X is for <unused>


Y Edit

  • Y is for YCMD

This is a combination of y_groups and y_commands to give custom syntax to defining commands just for one group (or not):


// Define a normal command:
Y:help(playerid, params[], help)
{
    // Do whatever.
}

// Define a command for only the group named "admin level 3":
Y<admin level 3>:ban(playerid, params[], help)
{
    // Do whatever.
}


Z Edit

  • Z is for <unused>

Download Edit

Download from pastebin.