Jump to content
Sign in to follow this  
calo_mir

Heli refuses to unload

Recommended Posts

Finally lost patience with this after a few hours of silent failure.

The map only contains a western soldier and two H pads named

h_source and h_dest, respectively.

init.sqf:

// Create passengers.
_team_0 = createGroup west;
"USMC_Soldier" createUnit [getMarkerPos "team_0_source", _team_0];
"USMC_Soldier" createUnit [getMarkerPos "team_0_source", _team_0];
"USMC_Soldier" createUnit [getMarkerPos "team_0_source", _team_0];

// Create crew, first member is pilot.
_heli_crew = createGroup west;
"USMC_Soldier_Pilot" createUnit [getMarkerPos "team_0_source", _heli_crew];
_heli_pilot = units _heli_crew select 0;

["MH60S", h_source, h_dest, _heli_pilot, _team_0] execVM "helidrop.sqf";

helidrop.sqf:

assert (count _this == 5);

_heli_class      = _this select 0;
_heli_source     = _this select 1;
_heli_dest       = _this select 2;
_heli_pilot      = _this select 3;
_heli_passengers = _this select 4;

assert (typeName (_heli_class)      == "STRING");
assert (typeName (_heli_source)     == "OBJECT");
assert (typeName (_heli_dest)       == "OBJECT");
assert (typeName (_heli_pilot)      == "OBJECT");
assert (typeName (_heli_passengers) == "GROUP");

// Create heli at source H.
_heli = _heli_class createVehicle (position _heli_source);
_heli setPos (position _heli_source);

// Move pilot into heli as driver.
_heli_pilot moveInDriver _heli;
_heli_pilot_group = group _heli_pilot;

// Move group into heli cargo.
{ _x moveInCargo   _heli;
 _x assignAsCargo _heli; } forEach units _heli_passengers;

// Tell heli to move to destination H and unload.
_heli_wp0 = _heli_pilot_group addWaypoint [position _heli_dest, 0];
_heli_wp0 setWaypointType "TR UNLOAD";
// Move heli back to source H.
_heli_wp1 = _heli_pilot_group addWaypoint [position _heli_source, 0];
_heli_wp1 setWaypointType "MOVE";

// Tell passengers to get out at H.
_passengers_wp0 = _heli_passengers addWaypoint [position _heli_dest, 0];
_passengers_wp0 setWaypointType "GETOUT";

Rather than move to the waypoint and unload the passengers, the heli

just sits in the air about 50m from the destination H pad. Tried all manner

of waypoint syncronization and can't get anything to work.

The intended effect is:

Take off.

Move to h_dest.

Drop passengers.

Move to h_source.

Any help would be appreciated.

---------- Post added at 09:10 PM ---------- Previous post was at 09:02 PM ----------

Oh, and a marker called team_0_source.

Share this post


Link to post
Share on other sites

And why script the whole thing when you can do the same with 3 objects and 2 waypoints in the editor?

Place the MH-60 in the editor, give it a name like "helo1", then place the player as cargo in it using

this moveInCargo helo1

in the players init line.

Next place an invisible H where the chopper should unload the unit.

Then select the chopper, and add an "transport unload" waypoint directly over the empty H. Another waypoint to the destination where the chopper shall land and done.

Share this post


Link to post
Share on other sites

This is a small part of a larger mission being developed independently. The vehicles specifically need to be created (and deleted later) dynamically.

I wouldn't be creating extra work for myself without good reason...

Share this post


Link to post
Share on other sites

When scripting this, I wouldn't use waypoints for it. But what you do is up to you, maybe someone posts a solution that uses waypoints later.

helidrop.sqf (blue code is new/changed):

assert (count _this == 5);

_heli_class      = _this select 0;
_heli_source     = _this select 1;
_heli_dest       = _this select 2;
_heli_pilot      = _this select 3;
_heli_passengers = _this select 4;

assert (typeName (_heli_class)      == "STRING");
assert (typeName (_heli_source)     == "OBJECT");
assert (typeName (_heli_dest)       == "OBJECT");
assert (typeName (_heli_pilot)      == "OBJECT");
assert (typeName (_heli_passengers) == "GROUP");

// Create heli at source H.
_heli = _heli_class createVehicle (position _heli_source);
_heli setPos (position _heli_source);

// Move pilot into heli as driver.
_heli_pilot moveInDriver _heli;
_heli_pilot_group = group _heli_pilot;

[color="Blue"]{_x assignAsCargo _heli;
_x moveInCargo   _heli; } forEach (units _heli_passengers);

_heli move (getpos _heli_dest);
waitUntil {unitReady _heli};
_heli land "GET OUT";
{unassignVehicle _x; } foreach (units _heli_passengers);
waitUntil { {_x in _heli} count (units _heli_passengers) == 0};
_heli move getpos (_heli_source);[/color]

Share this post


Link to post
Share on other sites

Thanks, I'll try it.

Waypoints aren't a necessity by any means. Whatever works.

---------- Post added at 10:40 PM ---------- Previous post was at 10:00 PM ----------

Hm, well, it does work. There's one problem, though: if the heli comes under fire before it reaches the destination H, it'll most likely open fire and then just sit there in the sky if it manages to eliminate all targets.

---------- Post added at 11:10 PM ---------- Previous post was at 10:40 PM ----------

Trying some things involving repeatedly giving orders to the heli in a loop so that it doesn't get stuck, but that just seems like a crap workaround to a stupid problem, frankly.

---------- Post added at 11:47 PM ---------- Previous post was at 11:10 PM ----------

SIGH.

The AI actively ignores commands.

assert (count _this == 5);

_heli_class      = _this select 0;
_heli_source     = _this select 1;
_heli_dest       = _this select 2;
_heli_side       = _this select 3;
_heli_passengers = _this select 4;

assert (typeName (_heli_class)      == "STRING");
assert (typeName (_heli_source)     == "OBJECT");
assert (typeName (_heli_dest)       == "OBJECT");
assert (typeName (_heli_side)       == "SIDE");
assert (typeName (_heli_passengers) == "GROUP");

// Create heli at source H.
_heli = _heli_class createVehicle (position _heli_source);
_heli setPos (position _heli_source);

// Create pilot for heli.
_heli_crew = createGroup _heli_side;
"Pilot" createUnit [getPos _heli, _heli_crew];
_heli_pilot = units _heli_crew select 0;

// Move pilot into heli as driver.
_heli_pilot moveInDriver _heli;

// Move group into heli cargo.
{ _x moveInCargo   _heli;
 _x assignAsCargo _heli; } forEach units _heli_passengers;

// _vehicle has any member of _passengers as cargo?
_vehicle_has_passengers = {
 _vehicle    = _this select 0;
 _passengers = _this select 1;

 assert (typeName (_vehicle)    == "OBJECT");
 assert (typeName (_passengers) == "GROUP");

 _present = false;
 {
   if (_x in _vehicle) then { _present = true; }
 } forEach units _passengers;

 hint format ['%1 ? %2', time, _present];
 _present;
};

// Repeatedly try to deliver units.
_has_passengers = true;
while { _has_passengers } do {
 _has_passengers = [_heli, _heli_passengers] call _vehicle_has_passengers;

 _done = false;
 while { ! _done } do {
   _heli move (getPos _heli_dest);
   hint format ["%1 ordered to move...", time];

   _done = unitReady _heli;
   if (! _done) then { sleep 10; };
   hint format ["%1 move ready or timed out...", time];
 };

 _done = false;
 while { ! _done } do {
   // Order heli to land and deposit passengers.
   _heli land "GET OUT";
   hint format ["%1 ordered to get out...", time];

   _done = unitReady _heli;
   if (! _done) then { sleep 10; };
   hint format ["%1 get out ready or timed out...", time];
 };

 { unassignVehicle _x; } forEach (units _heli_passengers);
 waitUntil { { _x in _heli } count (units _heli_passengers) == 0 };
};

// Order heli to return home.
_heli move (getPos _heli_source);
waitUntil {unitReady _heli};

// Gone.
deleteVehicle _heli;
deleteVehicle _heli_pilot;
deleteGroup   _heli_crew;

Heli takes off, comes under fire from a Russian fire team. Circles a few times and usually destroys them. Then, it just hangs in the air and the hints show constant orders to move to the destination going completely ignored.

Share this post


Link to post
Share on other sites

This almost works perfectly:

assert (count _this == 5);

_heli_class        = _this select 0;
_heli_source       = _this select 1;
_heli_destinations = _this select 2;
_heli_side         = _this select 3;
_heli_passengers   = _this select 4;

assert (typeName (_heli_class)        == "STRING");
assert (typeName (_heli_source)       == "OBJECT");
assert (typeName (_heli_destinations) == "ARRAY");
assert (typeName (_heli_side)         == "SIDE");
assert (typeName (_heli_passengers)   == "GROUP");

// Create heli at source H.
_heli = _heli_class createVehicle (position _heli_source);
_heli setPos (position _heli_source);

// Create pilot for heli.
_heli_crew = createGroup _heli_side;
"Pilot" createUnit [getPos _heli, _heli_crew];
"Pilot" createUnit [getPos _heli, _heli_crew];
"Pilot" createUnit [getPos _heli, _heli_crew];
_heli_pilot = units _heli_crew select 0;
_heli_gun_0 = units _heli_crew select 1;
_heli_gun_1 = units _heli_crew select 2;

{ _x setSkill 1.0 } forEach units _heli_crew;

// Move pilot into heli as driver.
_heli_pilot moveInDriver _heli;
_heli_gun_0 moveInTurret [_heli, [0]];
_heli_gun_1 moveInTurret [_heli, [1]];

// Move group into heli cargo.
{ _x moveInCargo   _heli;
 _x assignAsCargo _heli; } forEach units _heli_passengers;

// Select destination at random from H pads.
_index     = floor random count _heli_destinations;
_heli_dest = _heli_destinations select _index;

assert (typeName (_heli_dest) == "OBJECT");

hint format ['selected destination %1', _index];

heli_wp0_done = false;
heli_wp1_done = false;

// Tell heli to move to destination H and unload.
_heli_wp0 = _heli_crew addWaypoint [position _heli_dest, 0];
_heli_wp0 setWaypointType "TR UNLOAD";
_heli_wp0 setWaypointBehaviour "COMBAT";
_heli_wp0 setWaypointSpeed "LIMITED";
_heli_wp0 setWaypointStatements ["true", "heli_wp0_done = true;"];

waitUntil { heli_wp0_done };

doGetOut (units _heli_passengers);
{ unassignVehicle _x; } foreach (units _heli_passengers);
waitUntil { {_x in _heli} count (units _heli_passengers) == 0};

_heli_wp1 = _heli_crew addWaypoint [position _heli_source, 0];
_heli_wp1 setWaypointType "MOVE";
_heli_wp1 setWaypointStatements ["true", "heli_wp1_done = true;"];

waitUntil { heli_wp1_done };

// Gone.
deleteVehicle _heli;
deleteVehicle _heli_pilot;
deleteVehicle _heli_gun_0;
deleteVehicle _heli_gun_1;
deleteGroup   _heli_crew;

There's a problem I'm hoping somebody knows how to fix: I'm having to explicitly wait for waypoints to complete, which is fine, but in order for the code in setWaypointStatements to work, the boolean values that specify whether a waypoint has been completed or not need to be global. This means that if I execute three copies of helidrop.sqf, they'll trample on each other.

How can I make a variable local to the script but still accessible from the code in setWaypointStatements?

I appreciate that this code is also not MP-safe. That's next...

Share this post


Link to post
Share on other sites

You could store this waypoint status information (heli_wp0_done, heli_wp1_done) in the variable space of the respective helicopter.

As every object has its own variable space, you won't have a conflict.

_heli setVariable ["heli_wp0_done", false];
// ...
_heli_wp0 setWaypointStatements ["true", "(vehicle this) setVariable [""heli_wp0_done"",true];"];
// ...
waitUntil { _heli getVariable "heli_wp0_done" };

instead of

heli_wp0_done = false;
// ...
_heli_wp0 setWaypointStatements ["true", "heli_wp0_done = true;"];
// ...
waitUntil { heli_wp0_done };

same goes for 'heli_wp1_done'

Share this post


Link to post
Share on other sites

Thanks very much. I didn't know objects had accessible internal state like that.

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  

×