Home   Help Search Login Register  

Author Topic: Problem with while do loop  (Read 1202 times)

0 Members and 1 Guest are viewing this topic.

Offline myke13021

  • Contributing Member
  • **
  • Myke
Problem with while do loop
« on: 16 Aug 2007, 20:25:24 »
I am starting learning this dam*** sqf synthax but at some points i don't get it. I've got this script which works fine upon the WaitUntil line but the rest goes through in notime

Code: [Select]
private ["_chopper", "_pilot", "_id", "_inrange", "_inheight", "_vehicle", "_xdist", "_ydist", "_zdist", "_x", "_pos", "_dist"];

_chopper = _this select 0;
_pilot = _this select 1;
if (driver _chopper != _pilot) exitwith {hint "You're not the Pilot."};
hint format ["Hook program activated for %1", typeof _chopper];
_id = _this select 2;
_chopper removeaction _id;
waituntil {(getpos _chopper select 2) > 1};
while {(isnull _vehicle)} do
{
_vehicle = nearestobject [_chopper, "LandVehicle"];
};
while {(! _inrange) and (! _inheight)} do
{
_xdist = ((getpos _chopper select 0) - (getpos _vehicle select 0));
_ydist = ((getpos _chopper select 1) - (getpos _vehicle select 1));
if ((_xdist < 1) and (_xdist > -1) and (_ydist < 1) and (_ydist > -1)) then {_inrange = true} else {_inrange = false};
_zdist = getpos _chopper select 2;
if (_zdist > 5) and (_zdist < 25) then {_inheight = true} else {_inheight = false};
hint format ["X-offset: %1\nY-offset: %2\nHeight: %3", _xdist, _ydist, _zdist];
};
_x = (getpos _freight select 2);
_dist = _chopper distance _vehicle;
hint format ["%1 attached.\nMax allowed speed: 100km/h", typeof _vehicle];
while {_x > -0.3} do
{
_pos = [getpos _chopper select 0, getpos _chopper select 1, (getpos _chopper select 2) - _dist];
_vehicle setpos _pos;
_vehicle setdir getdir _chopper;
_x = (getpos _vehicle select 2);
hint format ["%1", _x];
sleep 0.01;
};

As said, it waits at the WaitUntil line, but once the chopper is higher than 1 meter above ground, i get instantly the hint:

 attached.
Max allowed speed: 100km/h

which means the script runs through without waiting at any while do loop.

For sure i messed something completely up. I'm not too bad in .sqs but for .sqf i just started learning.
I know there's surely some excellent Chopper airlift script around, but by doin it myself, i learn it better.

Thanks for all help that will surely come.


Myke out

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Problem with while do loop
« Reply #1 on: 16 Aug 2007, 21:08:02 »
Check the comments

Code: [Select]
private ["_chopper", "_pilot", "_id", "_inrange", "_inheight", "_vehicle", "_xdist", "_ydist", "_zdist", "_x", "_pos", "_dist"];

_chopper = _this select 0;
_pilot = _this select 1;
if (driver _chopper != _pilot) exitwith {hint "You're not the Pilot."};
hint format ["Hook program activated for %1", typeof _chopper];
_id = _this select 2;
_chopper removeaction _id;
waituntil {(getpos _chopper select 2) > 1};

// Vehicle initialized to NULL, else your while will exit immediately
_vehicle = objNull;

while {(isnull _vehicle)} do
{
_vehicle = nearestobject [_chopper, "LandVehicle"];

        // Wait 1 second, else your loop will consume 100% of CPU
        Sleep 1;
};


// Both to false, else next while will exit immediately
_inrange = false;
_inheight = false;

while {(! _inrange) and (! _inheight)} do
{
_xdist = ((getpos _chopper select 0) - (getpos _vehicle select 0));
_ydist = ((getpos _chopper select 1) - (getpos _vehicle select 1));
if ((_xdist < 1) and (_xdist > -1) and (_ydist < 1) and (_ydist > -1)) then
        {
           _inrange = true;
        }
        else
        {
           _inrange = false
        };

_zdist = getpos _chopper select 2;

if ((_zdist > 5) and (_zdist < 25)) then
        {
           _inheight = true;
        }
        else
        {
           _inheight = false;
        };
hint format ["X-offset: %1\nY-offset: %2\nHeight: %3", _xdist, _ydist, _zdist];
       
        // Wait 0.1 secs, else your loop will eat all CPU
        Sleep 0.1;
};

_x = (getpos _freight select 2);
_dist = _chopper distance _vehicle;
hint format ["%1 attached.\nMax allowed speed: 100km/h", typeof _vehicle];
while {_x > -0.3} do
{
_pos = [getpos _chopper select 0, getpos _chopper select 1, (getpos _chopper select 2) - _dist];
_vehicle setpos _pos;
_vehicle setdir getdir _chopper;
_x = (getpos _vehicle select 2);
hint format ["%1", _x];
sleep 0.01;
};

Offline myke13021

  • Contributing Member
  • **
  • Myke
Re: Problem with while do loop
« Reply #2 on: 16 Aug 2007, 21:26:26 »
thx Mandoble. didn't knew i had to predefine _vehicle = objnull.

Now the script works as far as i didn't made a big mistake:

Code: [Select]
if ((_xdist < 1) and (_xdist > -1) and (_ydist < 1) and (_ydist > -1)) then
of course this line can't work in this way. It should check if the chopper is not further away than +- 1 meter relative to _vehicle's xy pos.

but didn't thought of that even if _xdist is smaller than one, it surely can be greater than -1 (+10 i.e.)

How can i calculate that it checks if the chopper is within +-1 meter in x and y axis?

Myke out.

:EDIT:
hmmm....i get completely confused..it should work since it's AND and not OR. But as soon the nearestobject recons the vehicle (which is about 50 meters or so) ir will try to attach the vehicle and immediately release it. *grml* these sqf are a pain in the a..  :D
« Last Edit: 16 Aug 2007, 21:31:15 by myke13021 »

Offline Mandoble

  • Former Staff
  • ****
    • Grunt ONE and MandoMissile suite
Re: Problem with while do loop
« Reply #3 on: 16 Aug 2007, 22:41:13 »
Code: [Select]
while {(! _inrange) and (! _inheight)} do
{
_xdist = ((getpos _chopper select 0) - (getpos _vehicle select 0));
_ydist = ((getpos _chopper select 1) - (getpos _vehicle select 1));

        // with 1m you will have terrible problems trying to get in range with the chopper, 3 now
        // hypothenuse used for horizontal distance SQRT(L1*L1 + L2*L2)
       
        _horiz_dist = sqrt(_xdist^2 + _ydist^2)
if (_horiz_dist < 3) then
        {
           _inrange = true;
        }
        else
        {
           _inrange = false
        };

_zdist = getpos _chopper select 2;

if ((_zdist > 5) and (_zdist < 25)) then
        {
           _inheight = true;
        }
        else
        {
           _inheight = false;
        };
hint format ["X-offset: %1\nY-offset: %2\nHeight: %3\nDist:%4", _xdist, _ydist, _zdist, _horiz_dist];
       
        // Wait 0.1 secs, else your loop will eat all CPU
        Sleep 0.1;
};

Offline myke13021

  • Contributing Member
  • **
  • Myke
Re: Problem with while do loop
« Reply #4 on: 16 Aug 2007, 22:51:59 »
thx mandoble, but something is still messy...to the point where it waits for the nearestobject it works, but as soon it detects the vehicle with nearestobject, the script runs straight to the end.

Code: [Select]
private ["_horiz_dist", "_chopper", "_pilot", "_id", "_inrange", "_inheight", "_vehicle", "_xdist", "_ydist", "_zdist", "_x", "_pos", "_dist"];

_chopper = _this select 0;
_pilot = _this select 1;

_vehicle = objnull;
if (driver _chopper != _pilot) exitwith {hint "You're not the Pilot."};
hint format ["Hook program activated for %1", typeof _chopper];
_id = _this select 2;
_chopper removeaction _id;
waituntil {(getpos _chopper select 2) > 1};
while {(isnull _vehicle)} do
{
_vehicle = nearestobject [_chopper, "LandVehicle"];
sleep 1;
};
_inrange = false;
_inheight = false;
while {(! _inrange) and (! _inheight)} do
{
_xdist = ((getpos _chopper select 0) - (getpos _vehicle select 0));
_ydist = ((getpos _chopper select 1) - (getpos _vehicle select 1));
_horiz_dist = sqrt(_xdist^2 + _ydist^2);
if (_horiz_dist < 3) then
{
_inrange = true;
}
else
{
_inrange = false;
};
_zdist = getpos _chopper select 2;
if ((_zdist > 5) and (_zdist < 25)) then
{
_inheight = true;
}
else
{
_inheight = false;
};
hint format ["X-offset: %1\nY-offset: %2\nHeight: %3\nDist:%4", _xdist, _ydist, _zdist, _horiz_dist];
Sleep 0.1;
};
_x = (getpos _vehicle select 2);
_dist = _chopper distance _vehicle;
hint format ["%1 attached.\nMax allowed speed: 100km/h", typeof _vehicle];
while {_x > -0.3} do
{
_pos = [getpos _chopper select 0, getpos _chopper select 1, (getpos _chopper select 2) - _dist];
_vehicle setpos _pos;
_vehicle setdir getdir _chopper;
_x = (getpos _vehicle select 2);
sleep 0.01;
if (speed _chopper > 100) exitwith {hint format ["Speed: %1km/h\nAllowed: 100km/h\n%2 dropped.", speed _chopper, typeof _vehicle]};
};
hint format ["%1 released.", typeof _vehicle];
_chopper addaction ["Hook", "liftup.sqf"];
This is how the whole script looks like right now, including your last corrections, mandoble. It seems as it doesn't wait for _inrange and _inheight becoming true.


:EDIT:
Mandoble, if you have time to, would you mind to contact me on msn? Cause this thing is causing me headache. But i bet you got enough other things to do.
« Last Edit: 16 Aug 2007, 22:59:56 by myke13021 »

Offline LCD

  • Former Staff
  • ****
    • Everon Cartel
Re: Problem with while do loop
« Reply #5 on: 17 Aug 2007, 00:07:03 »
mebe ur choper is flyin 2 low ?

wat flyinheigh is it set 2 ?

LCD OUT
"guess being the community has downsides .." - cheetah
Help Perfecting Da Next Best Thing - O-Team Beta

Offline Mr.Peanut

  • Former Staff
  • ****
  • urp!
Re: Problem with while do loop
« Reply #6 on: 21 Aug 2007, 15:57:31 »
Do you want both _inrange and _inheight to be true, or just one of them? ATM only one of them has to be true to exit the loop. I think you want:
Code: [Select]
while {(! _inrange) or (! _inheight)} do
A small style comment. This loop is indented such that it looks like it is part of the preceeding loop which it isn't.
« Last Edit: 21 Aug 2007, 16:04:57 by Mr.Peanut »
urp!