Personnaly I use get XZ_ATAN(17) to get the current heading of the unit. At first look it may seems strange to have only a constant, and to not mention any piece, but that is because, hmm, lemme quote
a year old post of mine:
Smoth wrote:However, I would LOVE! to see the script for the north south lock.
zwzsg wrote:Ok.
I have made some long ago for my 2D units, but only recently[1 year ago now], I understood the proper way and wrote it properly.
[...]
The new cleaner north south lock script has been used only on [...]
It reads:
turn philactere_tourrelle to y-axis get XZ_ATAN(17) now;
turn philactere_pencheage to x-axis <26.565> now;
26.565° is the angle between TA camera and the vertical, so I turn the piece of that angle to make sure it's parallel to surface of the screen and not to the the ingame horizontal surface. [irrelevant in Spring of course]
The interesting part is get XZ_ATAN(17).
Normally, the get XZ_ATAN(...) function is only used on a XZ difference. For instance, a typical use of XZ_ATAN would be:
turn loading_arm to y-axis get XZ_ATAN(get PIECE_XZ(base) - get UNIT_XZ(unit_id));
Basically, you feed that get XZ_ATAN(...) with a XZ difference, and it spouts the angle of the line between the two points you made the difference of.
A much important property of that function is that while the XZ are in the global coordinate and axis system, the angle is given into the local coordinate and axis system, the one tied to the unit. That is, in the exemple get XZ_ATAN(get PIECE_XZ(base) - get UNIT_XZ(unit_id)); the result will be 0=<0> (or maybe 32768=<180>, I often get confused) if the unit we want to load is in front of the transport. (Yes, the get XZ_ATAN(...) originally comes from the ship and hover transport scripts, but don't worry, you can use it in any script fine, transports just happen to be the units that traditionally use it).
So, what it means, is that when we give get XZ_ATAN(...) the difference between two absolute XZ coordinates, it calculates the absolute angle, then adds the offset angle of the unit
Now comes the tricky part: we just completly reverse the traditional use of get XZ_ATAN(...), instead of feeding it with an unknown angle to get that angle in the unit axis system, we feed it a known absolute angle, so as to read where is the zero of the local coordinate system. Knowing where that zero is placed tell us what is the unit direction.
So in fact we just feed it a cardinal point coordinate and read the difference to zero (that is, the value itself) of the output.
We understand get XZ_ATAN(vector_with_a_known_angle) as giving the angle between the unit direction and the known angle. Probably with a minus sign thrown in.
Since the way TA use to pack x and z into a xz is: xz=(x/65536) *65536 + (z/65536), you have
get XZ_ATAN(z') with 0<z'<65535 gives the angle between the unit heading and the north**
get XZ_ATAN(-z') with 0<z'<65535 gives the angle between the unit heading and the south**
get XZ_ATAN(65536*x') with 0<x'<65535 gives the angle between the unit heading and the west***
get XZ_ATAN(-65536*x') with 0<x'<65535 gives the angle between the unit heading and the east***
** There is a 50% that I confused north and south
*** There is a 50% that I confused west and east
And don't dismiss the possibility that I confused north-south and east-west too
So a line like:
turn shoulder to y-axis get XZ_ATAN(0-458752) now;
may look completly odd, but is the way to ensure that all the children of shoulder have their x and z axis aligned to the map x and z, (naming "map x+" the south and "map z+" the east)
Oh, and somehow my name written in explosion was mirror-inverted and not placed at the top left corner of the map under Spring, so I guess Spring doesn't work exactly the same. [note: I now believe it's the way spring position explosions which is wrong, the angle reading being (mostly) similar to TA]
[....]
Now, for a pratical exemple, heads over to
Wormhole production and get my Arm Duck amphibious transport. I recall testing it to make sure it's Spring compatible, and if my memory serves me well, this is the most recent exemple of such a script I wrote. Skip the whole lengthy transportation scripty and go straight for the MovementAnimation() function.
The core of the part that interest us right now is:
var unitheading;
[...]
while(1)
{
unitheading=unitheading - get XZ_ATAN(7);//now it's unit heading diff
turn wheel1 to y-axis 3*unitheading speed <40>;
turn wheel2 to y-axis 3*unitheading speed <40>;
turn wheel3 to y-axis 1*unitheading speed <40>;
turn wheel4 to y-axis 1*unitheading speed <40>;
turn wheel5 to y-axis 0-1*unitheading speed <40>;
turn wheel6 to y-axis 0-1*unitheading speed <40>;
turn wheel7 to y-axis 0-3*unitheading speed <40>;
turn wheel8 to y-axis 0-3*unitheading speed <40>;
unitheading=get XZ_ATAN(7);//Now it's actually the unit heading (or the opposite, and maybe shifted 180°)
[...]
sleep 300;
}
You mentionned many times having issues because you don't know what range are the angle resulting in the difference of two angles. There is a simpe way around:
your_angle= angle blabla from stuff ATAN stuff stuff - another angle blabla from stuff ATAN stuff stuff;
while(your_angle<0)
{
your_angle=your_angle +65536;
}
while(your_angle>32767)
{
your_angle=your_angle -65536;
}
//There, now your angle has been modulo'ed to the <-180> <180> range.
//If you prefer <0> <360> range, just invert the order of the whiles.
Lastly, in TA, the xz plane is always horizontal, but I'm under the impression (not yet sure) that in Spring the xz plane tilt with the slope on non upright units. But in both TA and Spring the x and z got with get PIECE_XZ(..) and get UNIT_XZ(..) are absolute map coordinate
(ok, previous statment just contradicted that around a bit) And both in Spring and TA, the get XZ_ATAN(..) gives an angle relative to the unit heading.