Integer type in jass is a long signed int meaning each of them takes 32 bits: 31 for a number and one for a sign. In Jass integer can be presented in 8 (octimal), 10 (decimal), 16 (hexadecimal) and 256(ASCII) notation.
I'll explain this briefly (if you are familiar with various notations you can go straight to the practics). In a decimal notation we increment greater order when the lesser one becomes more than or equal to 10(9+1=10). This applies to other notations as well, corrected that they "trigger" on their own bases. Meaning we change greater order after getting 8 in octimal and 16 in hexadecimal. By the way, we use only ten figures, so how to write figure ten, figure eleven and so on? In hexadecimal notation figures representing numbers greater than 9 are replaced with capital latin letters. So, "A" means "10", "B" means "11" et cetera(You can go further and advance it up to 36-based notation). ASCII follows the same idea, but it uses chars' codes instead. For reference look into this table(taken from WEU documentation):
If zero is placed before an integer number that number is written in octimal. (localintegeri=012// 10 in deciman) Hexadecimals use 0x in the same way. (localintegeri=0x0f// 15 in dec)And if a number is marked by inverted commas you have rawcode ASCII notation. (localintegeri='A'// 67 dec). If you want to translate number from one notation to another you can use WinCalc (switched to engineering mode). Translation to ASCII is simple as well: you can translate every "figure" using charcode table and afterwards write resulting codes as they follow. For example, 'A0a1': 'A' = 0x41, '0' = 0x30, 'a' = 0x61, '1' = 0x31, so 'A0a1' means 0x41306131 or 1093689649.
Note that each rawcode is nothing but an integer, and therefore we can do any kind of mathematical operations with them. Look forward for examples.
In Jass there is no possibility to present number in binary notation, but it is very important for us to know about it. As you might have understood, binary notation follows the same rules as octimal, decimal and hexadecimal: greater order (which is called here bit) appears when we get 2 or more in lesser: 1bin+1bin == 10bin (2dec). Now let's go back to our 32-bit integer:
Code:
0x 7 a 9 8 0 1 f 0
0111 1010 1001 1000 0000 0001 1111 0000
I shall notice, that the first bit is a sign bit, it determines whether number is positive (0) or negative (1). Positive numbers range from 0x00000000 (0dec) to 0x7fffffff (2147483647dec), negative range from 0xffffffff (-1dec) to 0x80000000 (-2147483648dec). When switching sign we have to change all bits' values to their opposites and have to add 1.
In examples I will use single bytes so it is simplier to understand:
Bits that do not fit the result will be considered lost. Now, with the help of two shifts we can receive any bits we need:
Code:
0110 1101 // *1000
0110 0000 // /100000
0000 0011
We caught some problems with the sign bit:
Code:
0111 1100 // *1000
1110 0000 // 1110 0000bin - -20dec
1110 0000 // but we can change value a bit
+1000 0000
_____ _____
1 0110 0000
We also can use separator bit to be sure that after our multiplication sign bit is equal to 0:
Code:
0vv- vvvv
v - our values
I shall add that multiplication / division on 10bin, 100bin, 1000bin is also left shift/right shift on 1, 2, 3 bits(2^1 == 2 dec == 10 bin; 2^2 == 4 dec == 100 bin; 2^3 == 8 dec == 1000 bin; 2^n == shift on n bits).
That's all for theory, now I'll show examples of how to get it working.
Practics
For example, there are some simple problems with their solution.
Bonus gold
We have to add bonus gold depending on killer's stats (for example the unit has item or ability adding +50 % gold from creeps), and thus on a map there is simply a heap of creeps, each of them can drop completely different quantity of gold. There is a function creating texttag, it takes how much gold we add. Let's assume two variants, in the first 1 <=minGold <=maxGold <80000000, in the second 1 <=minGold <=MaxGold <=75
Adding item
We have a map containing 60 types of custom heroes. When hero achieves level 25 there pops a specific artifact at its feet.
Private unit data
It is necessary to memorize for ingame units how many ennemies and heroes they killed, and also on which side they battle (for example light or darkness). Presumably the unit cannot kill more 2000 units, cannot kill more than 500 heroes, and is either good or evil. There is presumably a lot of recipient units. The main condition of a problem - we cannot use cache nor variables nor arrays (only local scope).
Solution of problems
Solution of problems
Bonus gold
JASS:
globalsrealarraygoldMinrealarraygoldMax// Two arrays in which and// The information on gold will be storedendglobalsfunctionInittakesnothingreturnsnothingsetgoldMin[0x00]=1setgoldMin[0x01]=25setgoldMin[0x02]=12setgoldMin[0x03]=85setgoldMin[0x04]=10setgoldMin[...n]=nsetgoldMax[0x00]=5setgoldMax[0x01]=28setgoldMax[0x02]=15setgoldMax[0x03]=285setgoldMax[0x04]=12setgoldMax[...n]=nendfunction
Now, the part of a file is designated as 0x00, meaning 0x75303030-0x75303030 (i.e. ' u000 '-'u000 '), 0x01 == 0x7530303 1 -0x75303030 (' u001 '-'u000 ')
It's quite a simple variant, the only thing that is necessary to keep in mind is that rawcodes have to be close to each other: <raw code>-0x75303030 < 8190 (maximum size of a array, 0x75303030 in our case)
I think it rather convenient and simple to compare to the majority of objects or of properties. And now we shall try to use rawcode itself for carrying information in it:
Code:
0000 0000 0000 0000 0000 0000 0000 0000
---- ---- xaaa aaaa xbbb bbbb ---- ----
a - min gold, b - max.
For a unit 'h1<0' it will give from 1 to 12, and for 'u\{1' - from 44 to 75 gold. In rawcode we can freely use chars from 0x30 to 0x7b, I think it is a simple enough and elegant decision;)
Too simple? Yes, it will work be even for a pair of hundreds heroes, single condition is that item's rawcode must be more hero's rawcode by 0x01000000, i.e. for the hero 'H000' the item 'I000', for 'H005' - 'I005' will be created. But it's quite a work to make them fit, I'd say.
Private unit data
Now, as you might have guessed we shall try to keep in unit's UserData three values at once:
A - creeps counter, value from 0 to 2047, B - hero counter, from 0 to 511, and C - bool is this unit holy (1==holy, 0==evil)
JASS:
//increases creeps counter on 1functionIncCCtakesunitureturnsnothingcallSetUnitUserData(u, GetUnitUserData(u)+0x00100000)
endfunction//how many creeps this unit has killedfunctionGetCCtakesunitureturnsintegerreturnGetUnitUserData(u)/0x00100000endfunction//increases hero counter on 1functionIncHCtakesunitureturnsnothingcallSetUnitUserData(u, GetUnitUserData(u)+0x00000400)
endfunction//how many heroes this unit has killedfunctionGetHCtakesunitureturnsintegerreturnGetUnitUserData(u)*0x00001000/0x00400000endfunctionfunctionMakeUnitEviltakesunitureturnsnothinglocalintegeri=GetUnitUserData(u)
ifi*0x00400000/0x40000000==0x01thencallSetUnitUserData(u, i-0x00000100)
endifendfunctionfunctionMakeUnitHolytakesunitureturnsnothinglocalintegeri=GetUnitUserData(u)
ifi*0x00400000/0x40000000==0x00thencallSetUnitUserData(u, i+0x00000100)
endifendfunctionfunctionGetUnitPropensitytakesunitureturnsnothingreturnGetUnitUserData(u)*0x00400000/0x40000000endfunction
Well, like everything genial it is simple xD. Also I shall add that in units UserData it is possible to place two structures and two boolean:
yes, thanks
but imho this tutorial about jass... hmm
misk: "Contains tutorials that do not fit into one of the above catagories" though it to solve to you)