Jump to content
Sign in to follow this  
NickThissen

Helicopter extraction not working

Recommended Posts

I am trying to create a simple helicopter extraction at the end of my co-op mission. I have read various tutorials and watched video's and I still cannot get it to work. I've tried two slightly different approaches and both get close but not quite there...

Approach 1:

I have a helicopter 'helo' somewhere far away over the ocean. I have set 'allowFleeing' to 0 so that it lands even if under enemy fire. It has one MOVE waypoint close to it, synced to a trigger that should start the extraction (helo does not move until the trigger is fired - works).

Then there is a LOAD waypoint at the LZ, close to a Helipad (invisible) object where I want the helo to land. In the 'On Act' of this waypoint, I wrote:

doStop helo; helo land "get in";

The next waypoint is a HOLD waypoint, very close to the LOAD waypoint, and with a condition that checks if all players are either dead or in the helo (so far only me as "p1"):

((!alive p1) OR (p1 in helo));

Finally there is a MOVE waypoint far over the ocean that goes through the end game trigger.

When I run this mission, the helo lands at the designated LZ and waits for me to get in (good). When I get in it takes off again, but it does not fly away; it hovers in mid air indefinitely and never continues to the next waypoint.

Approach 2:

Almost the same as approach 1, except I have changed the HOLD waypoint to a MOVE waypoint (the one after the LOAD waypoint, that's how I keep seeing it in tutorials). This time the helo does not wait for me to get in; it lands, then takes off again immediately and flies away. It does not even fly away to the next waypoint, at least as far as I can see, it goes in the opposite direction... Maybe it will turn around later I'm not sure.

Anyway, two approaches with two failed outcomes, I need a mix of the two... Can anyone help me out what am I doing wrong?

Share this post


Link to post
Share on other sites

"The next waypoint is a HOLD waypoint"

This may be your problem. The 'hold' waypoint either needs a script to break the unit out of it, or it needs a switch trigger. If neither of those are met, it will hold the position indefinitely... Try using either a switch, or a script call to make it move on.

For you second try, are you remembering to tell it to 'waituntil'? For example, if you're counting by group members, I would say:

waituntil {({_x in chopper} count units mygroup) == ({alive _x} count units mygroup)};

and then once satisfied, I'd dynamically create the next waypoint using a script.

If you set your Extraction though a script, it would probably be much easier...

for example, something like this (Although I haven't tested myself, so it may require tweaking a bit, but the idea is sound)

_wp0 = group chopper addWaypoint [ getpos Rescue_location, 50]; 
//Adds a waypoint at a given location, can be player, marker, invis. chopper pad, etc

_wp0 setWaypointType "MOVE";
//Sets waypoint type, in this case, you want MOVE

_wp0 setWaypointStatements ["true", "chopper land 'land'"]; 
//tells the chopper that once it evaluates true, initiate landing

waituntil {({_x in chopper} count units mygroup) == ({alive _x} count units mygroup)};
//Conditional that tells the chopper to wait until all alive units in group are seated in chopper
//This can be counted a number of different way, I just so happened to choose grouping

_wp1 = group chopper addWaypoint [getpos base, 50];
//Sets the choppers new waypoint location, again, can be pretty much anything, I chose to get
//position of my base...

_wp1 setWaypointType "MOVE";
//Again, you want the waypoint MOVE

_wp2 = group chopper addWaypoint [getpos base, 50];
Adds a second waypoint of a different type if you want the full unload

_wp2 setWaypointType "TR UNLOAD";
//If you want to see the unload, make type transport unload, this will land and unload chopper

_wp2 setWaypointStatements ["true", "chopper land 'land';"]; };
//Again, if evaluated true, land the chopper

That removes your reliance on the HOLD waypoint, by use of a conditional... just a thought though! :)

then you can just call it with a trigger

 nul = this execVM "script.sqf"; //Or whatever you choose to call the sqf file. 

^Just an example, there are many ways to do what you need

Also, I agree with the post below mine, I would use "get in" rather than land for the arrival waypoint, it's more fitting of an extraction, as they'll keep the rotors spinning. I was typing fast, and this was just a quick example script.

*One more quick thing, may I just point out that directly calling each player and checking if they're in the helicopter or dead is a big waste of space? You can "count" units a number of ways, per group, side, etc, and this lets you just run the loops above rather than referencing each individual unit. It also prevents the hard coding of names becoming an issue. For example, what if you change the name of P1 down the line? Then you'd have to go back an edit everything.

Edited by CodeMonkee

Share this post


Link to post
Share on other sites

I wouldnt use chopper land "land" on your first waypoint because the helicopter will land and then completely shut off, try chopper land "get in" instead.

Share this post


Link to post
Share on other sites

Thanks.

I have molded it into the following script which is called when I walk into a trigger (for testing purposes). The helicopter 'helo' is somewhere over the ocean and already flying.

if (!isServer) exitWith {};

// Add waypoint
_wp0 = group helo addWaypoint [getMarkerPos "heloLandMarker", 1];
_wp0 setWaypointType "MOVE";
_wp0 setWaypointStatements ["true", "helo land 'land'"];

// Wait for everyone to get in
_grp = group p1;
_inHeloCount = ({_x in helo} count units _grp);
_aliveCount = ({alive _x} count units _grp);
waituntil { _inHeloCount == _aliveCount };

// Take off 
_wp1 = group helo addWaypoint [getMarkerPos "heloEvacMarker", 1];
_wp1 setWaypointType "MOVE";

I don't need any more landing or unloading after extraction, the last waypoint is inside a large trigger that ends the mission.

The helicopter fails to land at the LZ (marker 'heloLandMarker' which is on top of an invisible helipad), but it does land "close" to it (not really, quite far away actually). Even worse: as soon as it lands the entire crew (including pilot) gets out and walks away (presumably to the waypoint? The waypoint was not reachable from where the landed so they just kind of walked around).

What am I doing wrong?

Share this post


Link to post
Share on other sites

create a radio trigger with this in it:

_heli = [blufor, group player, "B_Heli_Transport_01_camo_F", true] execVM "COB_extraction.sqf"

place a marker named heliSpawnMrk, this is where the helicopter spawns

place a marker named extractMrk, this is the pickup location

place a marker named baseMrk, this is the return position

COB_extraction.sqf

/*
Filename: COB_extraction.sqf
Author: cobra4v320

Description:
Spawns a helicopter at a marker location, the helicopter moves to another marker location and picks up a group of soldiers.
Prior to the helicopter touching down it will open both of its doors. When the group is in the helicopter the doors will close.
The helicopter will then move to another marker and drop off the group. Prior to landing the doors will open. When the
group gets out the doors will close and the helicopter will return to its spawn position and delete the crew, helicopter, and markers.
Requires pre-placed helicopter pads or place the marker over a pad that already has them like camp rogain or stratis airbase.

Parameter(s):
_this select 0: this is the side of the extraction helicopter (blufor, opfor, independent).
_this select 1: this is the group that the extraction helicopter will pick up.
_this select 2: the is the helicopter classname or type.
_this select 3: this will set the helicopter as captive, keeps the enemy from shooting at them. (default is false)

Example(s):
0 = [blufor, group player, "B_Heli_Transport_01_camo_F", true] execVM "COB_extraction.sqf" //this will spawn a ghosthawk and it will be setCaptive True
*/

if (!isServer) exitWith {};

hint "Extraction helicopter inbound";

_side = _this select 0;
_group = _this select 1;
_heliType = _this select 2;
_captive = if (count _this > 3) then {_this select 3} else {false};

_spawnPos = getMarkerPos "heliSpawnMrk";
_extractPos = getMarkerPos "extractMrk";
_basePos = getMarkerPos "baseMrk";
_spawnDir = [_spawnPos, _extractPos] call BIS_fnc_dirTo;

_helisv = [_spawnPos, _spawnDir, _heliType, _side] call BIS_fnc_spawnVehicle;
_heli = _helisv select 0;
_heliGroup = _helisv select 2;
_dir = direction _heli;
_heli setVelocity [sin(_dir)*60,cos(_dir)*60,0];

{
_x disableAI "AUTOTARGET"; 
_x disableAI "TARGET"; 
_x allowFleeing 0; 
_x setCaptive _captive;
} forEach (units _heliGroup);

_heli spawn {
   while { alive _this } do { 
       player action ["collisionlightOff", _this]; //turn off lights
       sleep 0.01;
   };
};

_wp0 = _heliGroup addWaypoint [_extractPos, 0];
_wp0 setWaypointType "MOVE";
_wp0 setWaypointSpeed "FULL";
_wp0 setWaypointBehaviour "CARELESS";
_wp0 setWaypointStatements ["true", "(vehicle this) land 'GET IN'; {(vehicle this) animateDoor [_x, 1]} forEach ['door_back_L','door_back_R','door_L','door_R']"];

waituntil {{_x in _heli} count (units _group) == {alive _x} count (units _group)};

{_heli animateDoor [_x, 0]} forEach ["door_back_L","door_back_R","door_L","door_R"];

_wp1 = _heliGroup addWaypoint [_basePos, 0];    
_wp1 setWaypointType "MOVE";
_wp1 setWaypointSpeed "FULL";
_wp1 setWaypointBehaviour "CARELESS";
_wp1 setWaypointStatements ["true", "(vehicle this) land 'GET OUT'; {(vehicle this) animateDoor [_x, 1]} forEach ['door_back_L','door_back_R','door_L','door_R']"];

waituntil {{_x in _heli} count (units _group) < 1};

{_heli animateDoor [_x, 0]} forEach ["door_back_L","door_back_R","door_L","door_R"];

_wp2 = _heliGroup addWaypoint [_spawnPos, 0];
_wp2 setWaypointType "MOVE";
_wp2 setWaypointSpeed "FULL";
_wp2 setWaypointBehaviour "CARELESS";
_wp2 setWaypointStatements ["true", "{deleteVehicle _x} forEach (crew vehicle this) + [vehicle this]"];

deleteMarker "heliSpawnMrk";
deleteMarker "extractMrk";
deleteMarker "baseMrk";

This is my old version I created a function, I will have to post it later.

Share this post


Link to post
Share on other sites

Wow, thanks! That finally works. (This should be a sticky or something, only thing that works for a proper extraction).

There is one more problem though: I put the 'basePos' marker (where it flies to after extraction) somewhere in the ocean in the middle of a large trigger that is set to end the game (activation blufor, type end#1). However, the trigger is not activated when the helicopter flies inside it. It is only activated when I leave the helicopter (essentially jumping out into the sea, but I don't get that far, as soon as I issue the 'eject' command the mission ends). Is the helicopter not seen as blufor for some reason? It's not the end of the world, I could direct it to a landing place somewhere and end the mission when we get out, but I don't like endless ending "movies" where you just fly to an airport that's miles away lol.

Another thing; I am assuming you set setcaptive to true so that the enemy doesn't shoot the helicopter? That's pretty clever, but maybe not very realistic. Do you have a better idea how to avoid the helicopter being damaged? Maybe resetting its damage in a loop or something? Also not too realistic but better than the enemy ignoring it completely.

Thanks again!

Share this post


Link to post
Share on other sites
Wow, thanks! That finally works. (This should be a sticky or something, only thing that works for a proper extraction).

There is one more problem though: I put the 'basePos' marker (where it flies to after extraction) somewhere in the ocean in the middle of a large trigger that is set to end the game (activation blufor, type end#1). However, the trigger is not activated when the helicopter flies inside it. It is only activated when I leave the helicopter (essentially jumping out into the sea, but I don't get that far, as soon as I issue the 'eject' command the mission ends). Is the helicopter not seen as blufor for some reason? It's not the end of the world, I could direct it to a landing place somewhere and end the mission when we get out, but I don't like endless ending "movies" where you just fly to an airport that's miles away lol.

Another thing; I am assuming you set setcaptive to true so that the enemy doesn't shoot the helicopter? That's pretty clever, but maybe not very realistic. Do you have a better idea how to avoid the helicopter being damaged? Maybe resetting its damage in a loop or something? Also not too realistic but better than the enemy ignoring it completely.

Thanks again!

Except that this is not the only way to do a "proper" extraction. There are many many different ways of implementing a helicopter extraction. However I'm happy this works for you! :)

The problem you are experiencing is most likely linked to setCaptive being true for the helicopter. Units that are setCaptive will not register in triggers as being of a certain side, therefore the trigger that you have detecting blufor will not fire when the helicopter passes through it.

If the chopper does not fly though your trigger before picking up the people, and only enters it on the way out, just set the trigger type to "anything" and GROUP it to the chopper. This would make it only fire when the chopper passed into it, regardless of captive status, and should act like you are intending.

Also, to your other comment, be careful of constant loops, they can sometimes cause a performance hit. However if you add pauses into the loops, you can also run the risk that in the time frame of the pause, however small, the helicopter may take enough damage and become destroyed, obviously complicating your mission. I try to avoid constantly calling values in a script unless I absolutely have to. But maybe this is just me, some may have other opinions as to the proper approach. However I would stick with the setCaptive approach, unless you absolutely have to change it,

Hope that helps!

Cheers,

CodeMonkee

Edited by CodeMonkee

Share this post


Link to post
Share on other sites

Well, I could not get any other method to work :)

Thanks, that makes sense about the captive setting. I have solved it for now to let the helicopter land at a small 'base' I made up out of some empty vehicles and some flags, looks pretty authentic, even better than ending the mission over the ocean. But I'll keep it in mind.

Share this post


Link to post
Share on other sites

Your final trigger should be group present anyways, or player in thislist. As for setcaptive its an option to use if you dont want your helicopter shot down. Another method is this allowdamage false. I have a better extraction script for this that I turned into a function. Maybe I will get it posted later.

Share this post


Link to post
Share on other sites
create a radio trigger with this in it:

_heli = [blufor, group player, "B_Heli_Transport_01_camo_F", true] execVM "COB_extraction.sqf"

place a marker named heliSpawnMrk, this is where the helicopter spawns

place a marker named extractMrk, this is the pickup location

place a marker named baseMrk, this is the return position

COB_extraction.sqf

/*
Filename: COB_extraction.sqf
Author: cobra4v320

Description:
Spawns a helicopter at a marker location, the helicopter moves to another marker location and picks up a group of soldiers.
Prior to the helicopter touching down it will open both of its doors. When the group is in the helicopter the doors will close.
The helicopter will then move to another marker and drop off the group. Prior to landing the doors will open. When the
group gets out the doors will close and the helicopter will return to its spawn position and delete the crew, helicopter, and markers.
Requires pre-placed helicopter pads or place the marker over a pad that already has them like camp rogain or stratis airbase.

Parameter(s):
_this select 0: this is the side of the extraction helicopter (blufor, opfor, independent).
_this select 1: this is the group that the extraction helicopter will pick up.
_this select 2: the is the helicopter classname or type.
_this select 3: this will set the helicopter as captive, keeps the enemy from shooting at them. (default is false)

Example(s):
0 = [blufor, group player, "B_Heli_Transport_01_camo_F", true] execVM "COB_extraction.sqf" //this will spawn a ghosthawk and it will be setCaptive True
*/

if (!isServer) exitWith {};

hint "Extraction helicopter inbound";

_side = _this select 0;
_group = _this select 1;
_heliType = _this select 2;
_captive = if (count _this > 3) then {_this select 3} else {false};

_spawnPos = getMarkerPos "heliSpawnMrk";
_extractPos = getMarkerPos "extractMrk";
_basePos = getMarkerPos "baseMrk";
_spawnDir = [_spawnPos, _extractPos] call BIS_fnc_dirTo;

_helisv = [_spawnPos, _spawnDir, _heliType, _side] call BIS_fnc_spawnVehicle;
_heli = _helisv select 0;
_heliGroup = _helisv select 2;
_dir = direction _heli;
_heli setVelocity [sin(_dir)*60,cos(_dir)*60,0];

{
_x disableAI "AUTOTARGET"; 
_x disableAI "TARGET"; 
_x allowFleeing 0; 
_x setCaptive _captive;
} forEach (units _heliGroup);

_heli spawn {
   while { alive _this } do { 
       player action ["collisionlightOff", _this]; //turn off lights
       sleep 0.01;
   };
};

_wp0 = _heliGroup addWaypoint [_extractPos, 0];
_wp0 setWaypointType "MOVE";
_wp0 setWaypointSpeed "FULL";
_wp0 setWaypointBehaviour "CARELESS";
_wp0 setWaypointStatements ["true", "(vehicle this) land 'GET IN'; {(vehicle this) animateDoor [_x, 1]} forEach ['door_back_L','door_back_R','door_L','door_R']"];

waituntil {{_x in _heli} count (units _group) == {alive _x} count (units _group)};

{_heli animateDoor [_x, 0]} forEach ["door_back_L","door_back_R","door_L","door_R"];

_wp1 = _heliGroup addWaypoint [_basePos, 0];    
_wp1 setWaypointType "MOVE";
_wp1 setWaypointSpeed "FULL";
_wp1 setWaypointBehaviour "CARELESS";
_wp1 setWaypointStatements ["true", "(vehicle this) land 'GET OUT'; {(vehicle this) animateDoor [_x, 1]} forEach ['door_back_L','door_back_R','door_L','door_R']"];

waituntil {{_x in _heli} count (units _group) < 1};

{_heli animateDoor [_x, 0]} forEach ["door_back_L","door_back_R","door_L","door_R"];

_wp2 = _heliGroup addWaypoint [_spawnPos, 0];
_wp2 setWaypointType "MOVE";
_wp2 setWaypointSpeed "FULL";
_wp2 setWaypointBehaviour "CARELESS";
_wp2 setWaypointStatements ["true", "{deleteVehicle _x} forEach (crew vehicle this) + [vehicle this]"];

deleteMarker "heliSpawnMrk";
deleteMarker "extractMrk";
deleteMarker "baseMrk";

This is my old version I created a function, I will have to post it later.

my god...this script is a lifesaver! I've been struggling with a helicopter extraction via the editor for weeks now

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  

×