Tips & Tricks
#61

I recently realized that bit-flags are actually used in SA-MP itself: Player keys.


There are 19 keys defined in a_samp.inc, and they are set to powers of 2 (1, 2, 4, 8, 16, 32, 64).

If you put this simple code within OnPlayerKeyStateChange:

pawn Code:
printf( "%019b", newkeys );


Then you\'ll notice how this looks exactly like the use of bit-flags in this topic. For those who don\'t know, this is also why you should always check keys with & instead of ==.


@Slice: Is this where you got the inspiration for bit-flags?
Reply
#62

Quote:
Originally Posted by LarzI
View Post
If you put this simple code within OnPlayerKeyStateChange:

pawn Code:
printf( "%019b", newkeys );


Then you\'ll notice how this looks exactly like the use of bit-flags in this topic.
Interesting.
Reply
#63

Quote:
Originally Posted by LarzI
View Post
For those who don\'t know, this is also why you should always check keys with & instead of ==.
There\'s a tiny problem that you might come across. Example:
pawn Code:
public OnPlayerKeyStateChange(playerid, newkeys, oldkeys)
{
    if (newkeys & KEY_FIRE) // 4
    {
        print("MSG 1");
    }
    if (newkeys & KEY_JUMP) // 32
    {
        print("MSG 2");
    }
    return 1;
}
If you press KEY_FIRE, it will print:
pawn Code:
MSG 1
/*
 * newkeys = 000100
 */
If you press KEY_JUMP while holding KEY_FIRE, it will print:
pawn Code:
MSG 1
MSG 2
/*
 * newkeys = 100100
 */
If you release KEY_JUMP while holding KEY_FIRE, it will print:
pawn Code:
MSG 1
/*
 * newkeys = 000100
 */
That\'s why there\'s a third parameter, which you can use to detect when a key is pressed and released (not if a key is being held down).
Reply
#64

All numbers in the assembler output are in hex, without leading zeroes and prefixes.
Reply
#65

Quote:
Originally Posted by Y_Less
Посмотреть сообщение
...
Isn't this the same as using -d0 (it removes breaks too)?
Reply
#66

Quote:
Originally Posted by Slice
Посмотреть сообщение
All numbers in the assembler output are in hex, without leading zeroes and prefixes.
Yeah that's what I thought. I only asked because I assumed he switched out the code, rather than running them after eachother, which caused confusion (Due to A being 10 in base10)
Reply
#67

Can I use ternary operator, bit-flags and multiple actions in one statement together? I mean like;
pawn Код:
//normal if-else statement
if(a == 0)
    a = 1;
    SetPlayerHealth(playerid, 100);
else
    a = 0;
    SetPlayerHealth(playerid, 0);

//ternary operator with multiple actions
a = (a == 0) ? 1, SetPlayerHealth(playerid, 100), print("Health: 100") : 0, SetPlayerHealth(playerid, 0), print("Health: 0");
//not sure here. correct me if I'm wrong  

//and how can I use bit flags with ternary operator?
enum test: (<< = 1)
{
    a, // question here; what happen if i dont put = 1? like a = 1,
    b
}
new test:player[MAX_PLAYERS];
//so i want to toggle a to 0 or 1 using ternary operator. how can i do that?
Reply
#68

Very useful, learned from this alot !
Reply
#69

Quote:
Originally Posted by newbienoob
Посмотреть сообщение
Can I use ternary operator, bit-flags and multiple actions in one statement together? I mean like;
pawn Код:
//normal if-else statement
if(a == 0)
    a = 1;
    SetPlayerHealth(playerid, 100);
else
    a = 0;
    SetPlayerHealth(playerid, 0);

//ternary operator with multiple actions
a = (a == 0) ? 1, SetPlayerHealth(playerid, 100), print("Health: 100") : 0, SetPlayerHealth(playerid, 0), print("Health: 0");
//not sure here. correct me if I'm wrong  

//and how can I use bit flags with ternary operator?
enum test: (<< = 1)
{
    a, // question here; what happen if i dont put = 1? like a = 1,
    b
}
new test:player[MAX_PLAYERS];
//so i want to toggle a to 0 or 1 using ternary operator. how can i do that?
All of these questions you can answer yourself by testing it out, fyi.

pawn Код:
a = (a == 0) ? 1, SetPlayerHealth(playerid, 100), print("Health: 100") : 0, SetPlayerHealth(playerid, 0), print("Health: 0");
That might work, but even if it does it's horribly confusing!

pawn Код:
enum test: (<< = 1)
{
    a, // question here; what happen if i dont put = 1? like a = 1,
    b
}
All of them will have value 0 because 0 << 1 is still 0.

pawn Код:
new test:player[MAX_PLAYERS];
//so i want to toggle a to 0 or 1 using ternary operator. how can i do that?
Not sure what you mean. Start off from the examples in the main post and work your way from there. You'll figure it out.


If you need a place to quickly test things, use this: http://slice-vps.nl:7070/
Reply
#70

Quote:
Originally Posted by Slice
Посмотреть сообщение
All of these questions you can answer yourself by testing it out, fyi.

pawn Код:
a = (a == 0) ? 1, SetPlayerHealth(playerid, 100), print("Health: 100") : 0, SetPlayerHealth(playerid, 0), print("Health: 0");
That might work, but even if it does it's horribly confusing!
I tested with the link you gave me(I don't have pawno) but it gives me errors.
Код:
input(6) : error 1: expected token: ":", but found ","
input(6) : error 1: expected token: ";", but found ":"
input(6) : error 29: invalid expression, assumed zero
input(6) : fatal error 107: too many error messages on one line
The codes
pawn Код:
main()
{
    new a;
    a = (a == 0) ? 1, print("1") : 0, print("0");
}


Quote:
Originally Posted by Slice
Посмотреть сообщение
pawn Код:
enum test: (<< = 1)
{
    a, // question here; what happen if i dont put = 1? like a = 1,
    b
}
All of them will have value 0 because 0 << 1 is still 0.
hmm I thought we should set it all to 0?


Quote:
Originally Posted by Slice
Посмотреть сообщение
pawn Код:
new test:player[MAX_PLAYERS];
//so i want to toggle a to 0 or 1 using ternary operator. how can i do that?
Not sure what you mean...
I mean like;
pawn Код:
enum ASD : (<< = 1)
{
    One = 1,
    Two,
    Three
}
new ASD:DSA[MAX_PLAYERS];

//So how can I use ternary operator here to set Two to 0 or 1?
Reply
#71

Explain what it is you want to do instead, and I'll show you the best way to do that.
Reply
#72

Ok, lets say that I want to make /duty command(admin duty on/off).
pawn Код:
//in normal way

new bool:Duty[MAX_PLAYERS];

CMD:duty(playerid)
{
    if(Duty[playerid] == false)
    {
        SendClientMessage(playerid, -1, "You are now on duty.");
        Duty[playerid] = true;
    }
    else
    {
        SendClientMessage(playerid, -1, "You are now off duty.");
        Duty[playerid] = false;
    }
    return 1;
}

//So can I use bit-flags and ternary operator together to create that command?

EDIT: here's another example
pawn Код:
enum DutyFlag:(<< = 1)
{
    Duty = 1
}
new DutyFlag:g_Duty[MAX_PLAYERS];

//OnPlayerConnect
g_Duty[playerid] = DutyFlag:0;


//Ok so, the main question is, can I change if-else statement in the command below to ternary operator?
CMD:duty(playerid)
{
    if(g_Duty[playerid] & Duty) *
    {
        g_Duty[playerid] |= Duty;
        SendClientMessage(playerid, -1, "Now on duty!");
    }
    else
    {
        g_Duty[playerid] &= Duty;
        SendClientMessage(playerid, -1, "Now off duty!");
    }
    return 1;
}
* I'm not sure here, is it 0?
Reply
#73

You can, but it's not worth it.

pawn Код:
g_Duty[playerid] = CONDITION ? (g_Duty[playerid] | Duty) : (g_Duty[playerid] & ~Duty);
Reply
#74

Got it! Thanks. What about this?

Quote:
Originally Posted by Slice
View Post
pawn Code:
a = (a == 0) ? 1, SetPlayerHealth(playerid, 100), print("Health: 100") : 0, SetPlayerHealth(playerid, 0), print("Health: 0");
That might work, but even if it does it's horribly confusing!
I tested with the link you gave me(I don't have pawno) but it gives me errors.
Code:
input(6) : error 1: expected token: ":", but found ","
input(6) : error 1: expected token: ";", but found ":"
input(6) : error 29: invalid expression, assumed zero
input(6) : fatal error 107: too many error messages on one line
The codes
pawn Code:
main()
{
    new a;
    a = (a == 0) ? 1, print("1") : 0, print("0");
}
Can I use multiple actions in ternary operator?
Reply
#75

You can, but not like that, and why would you? That's what structured "if"s are for - ternarys shouldn't really be used unless there's no alternative.
Reply
#76

1 line instead of many which makes my script looks simple and clean.
Btw, what am I doing wrong? Can you show me how?
Reply
#77

Trust me, it doesn't look either simple OR clean! One long line doing lots of different things is much more complicated than lots of lines each doing one thing.
Reply
#78

Ok, thank you for answering my questions.
Just one more question about "char-arrays".
Does it only for booleans? Can I put 'char' on every arrays? Like this;
pawn Code:
new
    bool:Duty[MAX_PLAYERS char],
    bool:Duty1[MAX_PLAYERS char],
    String[128 char],
    String1[128 char],
    Pickups[30 char],
    Pickups1[30 char];
Sorry if I'm asking so many questions. I'm learning
Reply
#79

You can put "char" on any array where the highest value to be stored will be 255, and the lowest 0 (or -128 - 127).
Reply
#80

Did you test bit-flags? BitFlag_Get macro awlays returns zero.
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)