if you want to ask question just open a topic, no need to shy
all these questions has been asked before on eathena
if it isn't down right now, I can just give you the links
now I have to explain all over again
1.
no, my example follows exactly the script_commands.txt
there's no different with these 2 codes
Code:
prontera,155,184,5 script sample#1 100,{.@charid = getcharid(0);getitem2 1601, 1, 1, 0,0, 255, 0, .@charid % pow(2,16), .@charid / pow(2,16); // <-- minegetitem2 1601, 1, 1, 0,0, 255, 0, .@charid & 65535, .@charid >> 16; // <-- script commands.txtend;}
both sentence will gives you same item
.
.
ok how to explain this ...
if your character has char_id of 150000
when you click the above script and look in the SQL table
Code:
select nameid, card0, card1, card2, card3 from inventory where char_id = 150000;
return -> 1601,255,0,18928,2
the card2 field - 18928 is actually the remainder of 216 -> .@charid % pow(2,16)
the card3 field - 2 is actually the division of 216 -> .@charid / pow(2,16)
so my sentence is just exactly match what I said
you can also try this
Code:
prontera,157,184,5 script sample#2 100,{mes "enter a player name";next;input .@input$;if ( !query_sql( "select char_id, name from `char` where name = '"+ escape_sql( .@input$ ) +"'", .@cid, .@name$ ) ) { // if there is no row return from the querymes "player not found";close;}mes "you get "+ .@name$ +"'s Rod";getitem2 1601, 1, 1, 0,0, 255, 0, .@cid % pow(2,16), .@cid / pow(2,16);close;}
.
.
ok so now you understand that card2 is remainder and card3 is division of char_id
now why do script_commands.txt use binary operations
its because computer actually process faster with just 0 and 1
since we are small we were taught in mathematics, that numbers are in 1,2,3,4,5,6,7,8,9,10
this is actually base 10 operations
example ... every time you update your server using new client, you change PACKETVER 20140115
21040115
I can play it with the script like this
Code:
prontera,159,184,5 script sample#3 100,{mes PACKETVER +""; // return 20140115mes "Year = "+ PACKETVER / 10000; // return 2014mes "Month = "+ PACKETVER / 100 % 100; // return 1 ( 01, the zero is omitted )mes "Day = "+ PACKETVER % 100; // return 15close;}
.
.
Part 2 : here comes bit-shifting operations
I assumed that you already know what is binary numbers
let say, I give a number -> 10101010
if you divide 101010 by 1, you'll get 101010
if you divide 101010 by 10, you'll get 10101
if you divide 101010 by 100, you'll get 1010
if you divide 101010 by 1000, you'll get 101
if you divide 101010 by 10000, you'll get 10
if you divide 101010 by 100000, you'll get 1
Code:
prontera,161,184,5 script sample#4 100,{.@num = 101010;dispbottom .@num / 1 +""; // return 101010dispbottom .@num / 10 +""; // return 10101dispbottom .@num / 100 +""; // return 1010dispbottom .@num / 1000 +""; // return 101dispbottom .@num / 10000 +""; // return 10dispbottom .@num / 100000 +""; // return 1end;}
same as
if you divide 101010 by 100, you'll get 101010
if you divide 101010 by 101, you'll get 10101
if you divide 101010 by 102, you'll get 1010
if you divide 101010 by 103, you'll get 101
if you divide 101010 by 104, you'll get 10
if you divide 101010 by 105, you'll get 1
Code:
prontera,163,184,5 script sample#5 100,{.@num = 101010;dispbottom .@num / pow( 10, 0 )+""; // return 101010dispbottom .@num / pow( 10, 1 ) +""; // return 10101dispbottom .@num / pow( 10, 2 ) +""; // return 1010dispbottom .@num / pow( 10, 3 ) +""; // return 101dispbottom .@num / pow( 10, 4 ) +""; // return 10dispbottom .@num / pow( 10, 5 ) +""; // return 1end;}
-> 10101010 / 100 = 10101010
-> 10101010 / 101 = 1010110
-> 10101010 / 102 = 101010
-> 10101010 / 103 = 10110
-> 10101010 / 104 = 1010
-> 10101010 / 105 = 110
and now, let's say I give a number 1010102, which is 4210
Code:
prontera,166,184,5 script sample#6 100,{.@num = 42;dispbottom ( .@num >> 0 )+""; // return 42dispbottom ( .@num >> 1 )+""; // return 21dispbottom ( .@num >> 2 )+""; // return 10dispbottom ( .@num >> 3 )+""; // return 5dispbottom ( .@num >> 4 )+""; // return 2dispbottom ( .@num >> 5 )+""; // return 1end;}prontera,168,184,5 script sample#7 100,{.@num = 42;dispbottom .@num / pow( 2, 0 )+""; // return 42dispbottom .@num / pow( 2, 1 )+""; // return 21dispbottom .@num / pow( 2, 2 )+""; // return 10dispbottom .@num / pow( 2, 3 )+""; // return 5dispbottom .@num / pow( 2, 4 )+""; // return 2dispbottom .@num / pow( 2, 5 )+""; // return 1end;}
both scripts do the same
-> 42 / 20 = 42
-> 42 / 21 = 21
-> 42 / 22 = 10
-> 42 / 23 = 5
-> 42 / 24 = 2
-> 42 / 25 = 1
equal to
-> 1010102 / 102 = 1010102 = 4210
-> 1010102 / 102 = 101012 = 2110
-> 1010102 / 102 = 10102 = 1010
-> 1010102 / 102 = 1012 = 510
-> 1010102 / 102 = 102 = 210
-> 1010102 / 102 = 12 = 110
so, you'll noticed a pattern
in base 10, to decrease the digits by removing the last digit, you do
number / 10
Example => 10101010 / 10 = 1010110
in base 2, to decrease the last bit, you do right shift
number >> 1
Example => 1010102 >> 1 = 101012
=> 4210 >> 1 = 2110
its the same when opposite
in base 10, to increase the digits by adding zero at the back, you do
number * 10
Example => 10101010 * 10 = 101010010
in base 2, to increase the bits by adding zero, you do left shift
number << 1
Example => 1010102 << 1 = 10101002
=> 4210 << 1 = 8410
another example ...
if I want cut 10101010 into half
in base 10 (decimal) operations, we do
Code:
prontera,150,180,5 script sample#8 100,{.@num = 101010;dispbottom .@num / 1000 +""; // return 101dispbottom .@num % 1000 +""; // return 10 ( 010, zero is omitted )end;}
if I want to cut 1010102 into half
in base 2 (binary) operations, 2 ways in athena script engine
Code:
prontera,152,180,5 script sample#9 100,{.@num = 42;dispbottom .@num / pow(2,3) +""; // return 5 -> 101 base 2dispbottom .@num % pow(2,3) +""; // return 2 -> 010 base 2end;}
Code:
prontera,154,180,5 script sample#10 100,{.@num = 42;dispbottom ( .@num >> 3 )+""; // return 5 -> 101 base 2dispbottom ( .@num & ( (1<<3) -1 ) )+""; // return 2 -> 010 base 2end;}
although both script do the same thing,
but the computer will compute 2nd sample, which using binary shift faster
because computer prefer to calculate numbers in binary form
so revise back ...
Code:
getitem2 1601, 1, 1, 0,0, 255, 0, .@charid % pow(2,16), .@charid / pow(2,16); // <-- minegetitem2 1601, 1, 1, 0,0, 255, 0, .@charid & 65535, .@charid >> 16; // <-- script commands.txt
if you go look at sql-files
https://github.com/HerculesWS/Hercules/blob/master/sql-files/main.sql#L104
the card fields are using smallint, which is 216
since 150000 is higher than 32768, that's why it is being split
150000 % pow(2,16) as card2 field
150000 / pow(2,16) as card3 field
.... actually binary shifting operation has another uses ... to store more information using lesser variables ...
which is part 3 ... damn eathena forum down really wasting my time writing again
however this post takes me almost 1 hour to write so meh ... some other time then