Jump to content
Sign in to follow this  
tophe

Problem with getPos and getPosASL

Recommended Posts

I'm working on my vehicle respawn script and I have a problem that I just don't know how to solve.

The vehicles positions is defined by:

_position = getPos _unit

and when the unit is destroyed it is spawned back by

_unit setPos _position;

Also it is checked for movement with:

if ((_unit distance _position > 10) then {do alot of code}....

This works great with any vehicle on land. But when a vehicle is put on the USS Khe Sanh (with the getposASL command),

it will tell the script that it has moved over 10 meters and trigger the if-statement from the beginning.

So, I tried swapping getPos for getPosASL and setPos for setPosASL, and then it works great on the ship.

But now the same problem has moved to the vehicles put on land.

Is there any way to get the Distance command to only meassure the X or Y axis and leave out the Z axis (since this seems to be the problem)?

Share this post


Link to post
Share on other sites

Cant you just set Z to 0 before calculating? Or better, convert to position2D? That's probably easiest.

Failing that, whip out your Trigonometry 101 book and make the calculations manually ;)

Share this post


Link to post
Share on other sites

Here's the trigonometry way:

// Takes two Arma-positions as argument and returns the 2D distance between them
private["_sij1","_sij2","_et"];
_sij1 = _this select 0;
_sij2 = _this select 1;

_et = sqrt( ((_sij2 select 0)-(_sij1 select 0))^2 + ((_sij2 select 1)-(_sij1 select 1))^2 );

_et

Edited by Fincuan

Share this post


Link to post
Share on other sites
Cant you just set Z to 0 before calculating? Or better, convert to position2D? That's probably easiest.

Failing that, whip out your Trigonometry 101 book and make the calculations manually ;)

The problem is that the position of the vehicle is constantly updated... T

he script always looks if the vehicle has moved 10 meters from the original spot.

How do I convert the position to 2D?

Also, haven't there been some talk about the modelToWorld command as a better solution for finding and manipulating positions?

Anyone that knows how to use that command?

Share this post


Link to post
Share on other sites

The last time I actually wrote a script with any kind of math in it was in the early days of OFP... I dont know if you can do a simple convert like in C++ (_pos2d = (Position2D)_position), but I dont see why _pos2d = [_position select 0, _position select 1] and _pos2d distance _anotherpos2d wouldnt work?

I cant imagine the distance command not working with both 2 and 3 figure arrays. You can probably do it directly in the if statement by cutting away z: if (([_unit select 0, _unit select 1] distance [_position select 0, _position select 1] > 10). Edit: eh well if _unit isnt a position maybe you need _unit getPos select 0, _unit etc etc.

This is rather wild speculation however. I really need to get up to speed on Arma coding lol.

Edited by Murklor

Share this post


Link to post
Share on other sites

why not checking the distance to the carrier (khe sanh), as it seems to move itself ?

_Dist=_unit distance _carrier;

//<loop start>

if(_unit distance _carrier != _Dist)then{
 _unit_has_moved = true;
}else{
 _unit_has_moved = false;
};

_Dist=_unit distance _carrier;
sleep _time;

//<loop end>

Share this post


Link to post
Share on other sites

The only problem here is that you are mixing getPos and getPosASL, which is why you're getting a difference on the z-axis.

You say you've replaced all getPos with getPosASL and all setPos with setPosASL ? Well that's how it would seem.

But you forgot this part:

if ((_unit distance _position > 10) then {do alot of code}...

_unit distance _position

the distance command can work with both units and positions... if you provide it with an unit instead of an position, it will get the position itself... well but it doesn't get the ASL position.

This should fix your problem:

if ((getPosASL _unit distance _position > 10) then {do alot of code}...

Keep everything else the way it is. :)

ps.:

sorry for lecturing but... guys, really !!! :eek:

convert a 3d position in 2d ? Just leave out the third coordinate !

And if you want an 2d distance you can always use the good old math-way:

xdis = pos2 select 0 - pos1 select 0;
ydis = pos2 select 1 - pos1 select 1;
xydis = sqrt(xdis*xdis + ydis*ydis);

or

this:

[pos1 select 0, pos1 select 1, 0]  distance [pos1 select 0, pos1 select 1,0]

pps:

The khe sanh doesn't move. It is an static object that is part of the map.

Edited by Tajin

Share this post


Link to post
Share on other sites

I did a quick test, and it seems to be working.

I have to do some more testing with the vehicles in different starting positions.

You're a freaking genius!

Thank you so much...

And thank all you others as well!

I did however run into a small new problem.

In my script there is an option to have an explosion when the wreck is deleted.

This is achieved by a simple

_effect = "M_TOW_AT" createVehicle getPosASL _unit;

The problem is that this works fine on the Khe Sanh, but if a vehicle is on the ground the bomb will spawn 20 meters in the air. So if I swap the getPosASL to getPos it works on ground, but not on Khe Sanh.

It seems the ASL messes up the Z axis for the bomb if the vehicle is on land.

Edited by Tophe

Share this post


Link to post
Share on other sites

Same problem as with the "distance" command. SetPos is how ArmA handles positions by default. If you have any command that uses a position as argument, it'll be an normal Position, not an ASL position.

Anyway, createVehicle does not place things precisely... vehicles for examples are placed at the nearest free position, instead of directly at the coordinates you provide.

Use an additional setPosASL command after the createVehicle.

Share this post


Link to post
Share on other sites

Hmmm.. weirdly enough it suddenly looks as if it started working.

I'll try the setPosASL as well. A bit wired though that the createVehicle could be 15-20 meters off, but only on the Z axis.

I'll try it out.

Thanks again man!

Share this post


Link to post
Share on other sites

I remember there was trouble with SetposASL in ArmA 1 (Z axis dependency on objects underneath, despite the 'above sea level' annotation), and I saw there was a new function SetposASL2 without this dependency. You could try SetposASL2 to see if that resolves your issues.

Edited by HitmanFF

Share this post


Link to post
Share on other sites

You're welcome.

Share this post


Link to post
Share on other sites

Right. Now everything seems to work fine.

Another thing I was thinking about...

Once in a respawn script I saw the command objNull being used after the unit was deleted before respawn.

I suppose that makes the _unit equal to nothing.

Is that done to ensure that the _unit is not in use before spawning a new vehicle to the handle? Is that a good idea?

Like this:

deleteVehicle _unit;
_unit = objNull;
_unit = _type createVehicle _position;

Would that make it more stable, do nothing or even make it worse?

Share this post


Link to post
Share on other sites

I guess that is just good programming practice, and it also makes sure _unit has a value in all scopes of the script. For example if that piece above looked like this:

deleteVehicle _unit;

if (condition) then {

[indent]_unit = _type createVehicle _position;[/indent]


};

_unit wouldn't have a value outside the if-statement. If you set it to any value before the if-part and then change the value within the "if" all works ok.

Share this post


Link to post
Share on other sites

ok.. But if _unit = objNull isn't that the same as _unit not having a value at all?

I always thought objNull meant the object is equal to nothing, not even itself.

Share this post


Link to post
Share on other sites

objNull is not the same as nil. You can think of objNull as a dummy object. Image something like this:

deleteVehicle _unit;
if (condition) then {
   _unit = _type createVehicle _pos;
};
removeAllWeapons _unit;

According to the BIKI accessing an already deleted object might crash ARMA. So if condition is false you're in trouble because _unit still references the deleted object! Setting _unit to objNull after the deleteVehicle will fix this.

The real problem in the above example, however, is sloppy coding. Move the removeAllWeapons inside the if..then block and the problem is gone.

In general it's not necessary to set a variable to objNull after deleteVehicle.

Share this post


Link to post
Share on other sites

Ok.. then I get it.

I might as well start using good coding practice then and put the objNull in there if it doesn't do anything negative, but might do something positive in a few instances.

Share this post


Link to post
Share on other sites
"Perfection is attained not when no more can be added, but when no more can be removed."

-- Antoine de Saint Exupéry

Cluttering code with "random stuff that might help" is not considered a good coding practice... ;)

Share this post


Link to post
Share on other sites
Cluttering code with "random stuff that might help" is not considered a good coding practice... ;)

Good point there ace!

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×