Posted
·
Edited by unequivocal Fix accidental emoticon
I've written a dynamic convoy ambush mission generator as part of a larger dynamic mission system (to be released soon).
When activated the script does the following:
Creates a well-armed convoy
Creates task for player to intercept/destroy
Shows start/end markers for convoy
Detects mission success/failure
I use the SecOp module a lot, but the ambush missions are usually disappointments. Often they are buggy and fail on start. Also the ambush task shows you the entire path of the convoy which seems too unrealistic - my system makes you figure out where to set up your ambush, and it's possible the convoy will go a different route.
This mission add-on is simply a single stand-alone script file. You can add it to any mission, and activate simply by including the file in your init.sqf and calling a single method to start the mission. Only one convoy ambush mission is permitted at a time.
Add to Init.sqf:
#include "convoyMission.sqf";
Call from code or trigger to activate mission:
call fSpawnEnemyConvoy;
I've also created a demo mission, so you can try it out without creating your own mission.
As this is my first post, I can't post the links, but here they are in plaintext:
Instructions for adding this into your own missions are in the script file itself. Please post here with questions/feedback.
I plan to add some additional features, like different kind of ambush missions (assassination, destroy specific guarded vehicle, etc). Feedback welcome on ideas for ambush missions.
Also, the entire script is here inside this spoiler if you want to access that way:
// Most basic way to use this script:
// Start with a blank map in editor
// Save map with a name (e.g. ConvoyMission)
// Go to that folder with a text editor (e.g., C:\Users\[Your user name]\Documents\ArmA 2\Missions\[mission name].[map])
// Create empty "init.sqf" file there
// Add single line in init.sqf: #include "convoyMission.sqf"
// Save this file to that folder
// Place "Ambient Combat Module" on map & sync to player
// Place Trigger on map:
// Activation: Radio Alpha
// Activation: Repeatedly
// Type: None
// On Act: call fSpawnEnemyConvoy;
// Axis a: 0
// Axis b: 0
// Save map. You can try it out with preview function in editor.
// To activate a convoy mission, press 0-0-1 within game
HQ = [West,"HQ"];
fHQMsg = {
[_this select 0] spawn {
msg = _this select 0;
sleep 4;
HQ sideChat msg;
};
};
// returns the direction (tangent) of a road segement based on connected road segment
// will return the direction closest to parameter "preferred angle"
// param1: road to get angle of
// param2: preferred angle -- return reciprocal angle closest to this angle
// returns integer heading of road
fGetRoadHeading = {
_road = _this select 0;
_preferredAngle = _this select 1;
_roadConnectedTo = roadsConnectedTo _road;
_connectedRoad = _roadConnectedTo select 0;
_angle = [_road, _connectedRoad] call BIS_fnc_DirTo;
_preferredMin = ((_preferredAngle-90)+360) mod 360;
_preferredMax = ((_preferredAngle+90)+360) mod 360;
// if the angle is "facing the wrong way" to our preferred angle
// return the reciprocal angle
if ((_angle > _preferredMin) && (_angle < _preferredMax)) then {
_angle = _angle;
}
else {
_angle = (_angle + 180) mod 360;
};
_angle;
};
// returns a data structure
// a array of position points based on starting position/angle
// returns the point on closest road to each point on the line
// each point is distance/angle further along line from previous point
// param1: startPoint
// param2: angle
// param3: distance
// param4: number of points
fGetArrayOfPointsOnRoadFromAngle = {
_startPos = _this select 0;
_angle = _this select 1;
_distance = _this select 2;
_num = _this select 3;
_startRoad = [_startPos, 0, 1000] call fGetNearestRoad;
_startPos = getPos _startRoad;
_retVal = [];
_lVal = _startPos;
// create _num entries of road positions
for "_x" from 1 to _num do {
_lVal = [_lVal, _angle, _distance] call fGetPointFromAngle;
// find empty position nearest this location, if any
_altVal = _lVal findEmptyPosition [0,10];
if (count _altVal > 0) then {
_lVal = _altVal;
};
_retVal = _retVal + [_lVal];
_nextRoad = [_lVal, 0, 1000] call fGetNearestRoad;
_lVal = getPos _nextRoad;
};
_retVal;
};
// returns a array of points based on starting position/angle
// each point is distance/angle further along line from previous point
// param1: startPoint
// param2: angle
// param3: distance
// param4: number of points
fGetArrayOfPointsFromAngle = {
_startPos = _this select 0;
_angle = _this select 1;
_distance = _this select 2;
_num = _this select 3;
_retVal = [];
_lVal = _startPos;
for "_x" from 1 to _num do {
_lVal = [_lVal, _angle, _distance] call fGetPointFromAngle;
_retVal = _retVal + [_lVal];
};
_retVal;
};
// returns a point that is specified distance/angle from point
// param1: startPos
// param2: angle
// param3: distance
fGetPointFromAngle = {
_startPos = _this select 0;
_startX = _startPos select 0;
_startY = _startPos select 1;
_startZ = _startPos select 2;
_angle = _this select 1;
_distance = _this select 2;
_endX = _startX + (_distance * sin _angle);
_endY = _startY + (_distance * cos _angle);
[_endX, _endY, _startZ];
};
// pass two positions, returns angle from pos1 to pos2
fGetAngleOfTwoPoints ={
_pos1 = _this select 0;
_pos2 = _this select 1;
_pos1_x = _pos1 select 0;
_pos1_y = _pos1 select 1;
_pos2_x = _pos2 select 0;
_pos2_y = _pos2 select 1;
_dx = _pos2_x - _pos1_x;
_dy = _pos2_y - _pos1_y;
_ang = _dx atan2 _dy;
_ang = _ang mod 360;
_ang;
};
//position to center search on
fGetNearestRoad={
_nearestRoad=objNull;
_closestDistanceToRoad=0;
_searchPos = _this select 0;
_minDistance = _this select 1;
_maxDistance = _this select 2;
_closestDistanceToRoad = _maxDistance;
{
if ((_searchPos distance _x < _maxDistance) && (_searchPos distance _x > _minDistance)) then {
_distanceToRoad = _searchPos distance _x;
if (_distanceToRoad < _closestDistanceToRoad) then {
_nearestRoad = _x;
_closestDistanceToRoad = _distanceToRoad;
};
};
} forEach (_searchPos nearRoads _maxDistance);
_nearestRoad;
};
// Function creates a random convoy intercept mission
// Randomizes starting and ending locations
// Uses semaphore to prevent multiple missions at the same time
// Creates task for player to intercept convoy
// Create triggers that monitors convoy death or convoy completed
// reset multi-mission semaphore
// clean up all waypoints
// fail task on convoy complete
// succeed task on convoy death
// Creates convoy units in a group
// Creates convoy waypoint at destination
// Creates start/end markers
// Cleans up markers, group and task on mission success/failure
fSpawnEnemyConvoy = {
if (convoyMissionAssigned) exitWith {
hint "Convoy mission is already assigned. Complete the assigned mission.";
};
_randomStartDistanceX = random 1000 - (1000/2);
_randomStartDistanceY = random 1000 - (1000/2);
_startPositionMin = 1500;
_startPositionMax = 3000;
_endPositionMin = 2000;
_endPositionMax = 4000;
convoyMissionAssigned = true;
convoyMarkers = [];
_playerUnit = player;
_searchPos = getPos _playerUnit;
// randomize the starting location +/- 100m
_searchPos = [(_searchPos select 0) + (_randomStartDistanceX), (_searchPos select 1) + (_randomStartDistanceY), _searchPos select 2];
_startRoad = [_searchPos, _startPositionMin, _startPositionMax] call fGetNearestRoad;
mkrConvoyStart = createMarker ["convoyMarkerStart", getPos _startRoad];
mkrConvoyStart setMarkerText "Convoy start";
mkrConvoyStart setMarkerType "Start";
mkrConvoyStart setMarkerColor "ColorRed";
mkrConvoyStart setMarkerAlpha 0.5;
//"Flag", "Flag1", "Dot", "Destroy", "Start", "End", "Warning", "Join", "Pickup", "Unknown", "Marker", "Arrow" or "Empty".
//markerName setMarkerPos pos
_searchPos = getMarkerPos mkrConvoyStart;
_endRoad = [_searchPos, _endPositionMin, _endPositionMax] call fGetNearestRoad;
mkrConvoyEnd = createMarker ["convoyMarkerEnd", getPos _endRoad];
mkrConvoyEnd setMarkerText "Convoy End";
mkrConvoyEnd setMarkerType "End";
mkrConvoyEnd setMarkerColor "ColorRed";
mkrConvoyEnd setMarkerAlpha 0.5;
// get the convoy pointing towards the ending marker
//_startAngle = [getMarkerPos mkrConvoyStart, getMarkerPos mkrConvoyEnd] call fGetAngleOfTwoPoints;
_startPos = getMarkerPos mkrConvoyStart;
_endPos = getMarkerPos mkrConvoyEnd;
_preferredAngle = [_startPos, _endPos] call BIS_fnc_DirTo;
_startAngle = [_startRoad, _preferredAngle] call fGetRoadHeading;
_startingPositions = [_startPos, _startAngle, -10, 10] call fGetArrayOfPointsOnRoadFromAngle;
_spawn = [_startingPositions select 0, _startAngle, "Offroad_DSHKM_INS", EAST] call BIS_fnc_spawnVehicle;
unit1 = _spawn select 0;
convoyGroup = _spawn select 2;
_wp = convoyGroup addWaypoint [_endPos, 0];
_wp setWaypointType "SAD";
_wp setWaypointBehaviour "SAFE";
convoyGroup setFormation "COLUMN";
// BUG: change behavior of entire group to alert on any awareness change/gunfire
//create the rest of the group with delays - to let the lead element get rolling
[_startingPositions, _startAngle] spawn {
_startingPositions = _this select 0;
_startAngle = _this select 1;
sleep 6;
_retVal = [_startingPositions select 1, _startAngle, "Ural_INS", convoyGroup] call BIS_fnc_spawnVehicle;
_transport = _retVal select 0;
groupConvoyEscort = [_startingPositions select 3, EAST, (configFile >> "CfgGroups" >> "East" >> "INS" >> "Infantry" >> "INS_InfSquad_Weapons"),[],[],[0.8,1],[],[12,1],_startAngle] call BIS_fnc_spawnGroup;
{_x moveInCargo _transport; sleep 0.05;} forEach units groupConvoyEscort;
sleep 10;
[_startingPositions select 2, _startAngle, "UralRefuel_INS", convoyGroup] call BIS_fnc_spawnVehicle;
sleep 6;
[_startingPositions select 3, _startAngle, "Pickup_PK_Ins", convoyGroup] call BIS_fnc_spawnVehicle;
sleep 6;
[_startingPositions select 4, _startAngle, "UAZ_AGS30_INS", convoyGroup] call BIS_fnc_spawnVehicle;
sleep 6;
[_startingPositions select 5, _startAngle, "TT650_Ins", convoyGroup] call BIS_fnc_spawnVehicle;
// we do this to improve their driving ability (hopefully)
{_x setSkill 1} forEach units convoyGroup;
hint "Convoy is enroute..";
};
// create task for player
convoyTask = _playerUnit createSimpleTask ["InterceptConvoy"];
convoyTask setSimpleTaskDescription ["We have intel of an armed Opfor convoy. Intercept and destroy it before it reaches the destination.", "Destroy Convoy", "Destroy Convoy"];
convoyTask setTaskState "Assigned";
["HQ here. We have intel of an armed Opfor convoy. Intercept and destroy it before it reaches the destination."] call fHQMsg;
// create trigger to detect convoy arrival to destination
trgDetectConvoyArrived = createTrigger ["EmptyDetector", _endPos];
trgDetectConvoyArrived setTriggerArea [100,100,0,false];
trgDetectConvoyArrived setTriggerActivation ["EAST", "PRESENT", true];
trgDetectConvoyArrived setTriggerStatements ["{vehicle _x in thislist} forEach units convoyGroup;", "[false] call fCleanUpConvoyMission;", ""];
// create trigger to detect convoy destruction
trgDetectConvoyDestroyed = createTrigger ["EmptyDetector", _endPos];
trgDetectConvoyDestroyed setTriggerArea [0,0,0,false];
trgDetectConvoyDestroyed setTriggerActivation ["NONE", "PRESENT", true];
trgDetectConvoyDestroyed setTriggerStatements ["({alive _x} count units convoyGroup) < 1;", "[true] call fCleanUpConvoyMission;", ""];
};
// removes all the markers and triggers for the mission
// param1: "Succeeded"/"Failed" -- sets task to success or failure
fCleanUpConvoyMission = {
_taskState = _this select 0;
if !(convoyMissionAssigned) exitWith {};
convoyMissionAssigned = false;
if (_taskState) then {
player sideChat "HQ, Alpha here. All convoy elements have been destroyed.";
["HQ here. Roger that, nice work."] call fHQMsg;
convoyTask setTaskState "Succeeded";
} else {
["HQ here. Intel reports that convoy has arrived at destination. Mission failed."] call fHQMsg;
convoyTask setTaskState "Failed";
{deleteVehicle vehicle _x; deleteVehicle _x;} forEach units convoyGroup;
};
trgDetectConvoyArrived = objNull;
trgDetectConvoyDestroyed = objNull;
deleteMarker mkrConvoyEnd;
deleteMarker mkrConvoyStart;
};
Dynamic Convoy Mission (better than SecOp ambush mission) script
in ARMA 2 & OA - ADDONS & MODS: COMPLETE
Posted · Edited by unequivocal
Fix accidental emoticon
I've written a dynamic convoy ambush mission generator as part of a larger dynamic mission system (to be released soon).
When activated the script does the following:
I use the SecOp module a lot, but the ambush missions are usually disappointments. Often they are buggy and fail on start. Also the ambush task shows you the entire path of the convoy which seems too unrealistic - my system makes you figure out where to set up your ambush, and it's possible the convoy will go a different route.
This mission add-on is simply a single stand-alone script file. You can add it to any mission, and activate simply by including the file in your init.sqf and calling a single method to start the mission. Only one convoy ambush mission is permitted at a time.
Add to Init.sqf:
Call from code or trigger to activate mission:
I've also created a demo mission, so you can try it out without creating your own mission.
As this is my first post, I can't post the links, but here they are in plaintext:
PBO Mission here: misuse.org/downloads/ConvoyMission.Chernarus.pbo
Script file here: misuse.org/downloads/convoyMission.sqf
Instructions for adding this into your own missions are in the script file itself. Please post here with questions/feedback.
I plan to add some additional features, like different kind of ambush missions (assassination, destroy specific guarded vehicle, etc). Feedback welcome on ideas for ambush missions.
Also, the entire script is here inside this spoiler if you want to access that way:
// Most basic way to use this script: // Start with a blank map in editor // Save map with a name (e.g. ConvoyMission) // Go to that folder with a text editor (e.g., C:\Users\[Your user name]\Documents\ArmA 2\Missions\[mission name].[map]) // Create empty "init.sqf" file there // Add single line in init.sqf: #include "convoyMission.sqf" // Save this file to that folder // Place "Ambient Combat Module" on map & sync to player // Place Trigger on map: // Activation: Radio Alpha // Activation: Repeatedly // Type: None // On Act: call fSpawnEnemyConvoy; // Axis a: 0 // Axis b: 0 // Save map. You can try it out with preview function in editor. // To activate a convoy mission, press 0-0-1 within game HQ = [West,"HQ"]; fHQMsg = { [_this select 0] spawn { msg = _this select 0; sleep 4; HQ sideChat msg; }; }; // returns the direction (tangent) of a road segement based on connected road segment // will return the direction closest to parameter "preferred angle" // param1: road to get angle of // param2: preferred angle -- return reciprocal angle closest to this angle // returns integer heading of road fGetRoadHeading = { _road = _this select 0; _preferredAngle = _this select 1; _roadConnectedTo = roadsConnectedTo _road; _connectedRoad = _roadConnectedTo select 0; _angle = [_road, _connectedRoad] call BIS_fnc_DirTo; _preferredMin = ((_preferredAngle-90)+360) mod 360; _preferredMax = ((_preferredAngle+90)+360) mod 360; // if the angle is "facing the wrong way" to our preferred angle // return the reciprocal angle if ((_angle > _preferredMin) && (_angle < _preferredMax)) then { _angle = _angle; } else { _angle = (_angle + 180) mod 360; }; _angle; }; // returns a data structure // a array of position points based on starting position/angle // returns the point on closest road to each point on the line // each point is distance/angle further along line from previous point // param1: startPoint // param2: angle // param3: distance // param4: number of points fGetArrayOfPointsOnRoadFromAngle = { _startPos = _this select 0; _angle = _this select 1; _distance = _this select 2; _num = _this select 3; _startRoad = [_startPos, 0, 1000] call fGetNearestRoad; _startPos = getPos _startRoad; _retVal = []; _lVal = _startPos; // create _num entries of road positions for "_x" from 1 to _num do { _lVal = [_lVal, _angle, _distance] call fGetPointFromAngle; // find empty position nearest this location, if any _altVal = _lVal findEmptyPosition [0,10]; if (count _altVal > 0) then { _lVal = _altVal; }; _retVal = _retVal + [_lVal]; _nextRoad = [_lVal, 0, 1000] call fGetNearestRoad; _lVal = getPos _nextRoad; }; _retVal; }; // returns a array of points based on starting position/angle // each point is distance/angle further along line from previous point // param1: startPoint // param2: angle // param3: distance // param4: number of points fGetArrayOfPointsFromAngle = { _startPos = _this select 0; _angle = _this select 1; _distance = _this select 2; _num = _this select 3; _retVal = []; _lVal = _startPos; for "_x" from 1 to _num do { _lVal = [_lVal, _angle, _distance] call fGetPointFromAngle; _retVal = _retVal + [_lVal]; }; _retVal; }; // returns a point that is specified distance/angle from point // param1: startPos // param2: angle // param3: distance fGetPointFromAngle = { _startPos = _this select 0; _startX = _startPos select 0; _startY = _startPos select 1; _startZ = _startPos select 2; _angle = _this select 1; _distance = _this select 2; _endX = _startX + (_distance * sin _angle); _endY = _startY + (_distance * cos _angle); [_endX, _endY, _startZ]; }; // pass two positions, returns angle from pos1 to pos2 fGetAngleOfTwoPoints ={ _pos1 = _this select 0; _pos2 = _this select 1; _pos1_x = _pos1 select 0; _pos1_y = _pos1 select 1; _pos2_x = _pos2 select 0; _pos2_y = _pos2 select 1; _dx = _pos2_x - _pos1_x; _dy = _pos2_y - _pos1_y; _ang = _dx atan2 _dy; _ang = _ang mod 360; _ang; }; //position to center search on fGetNearestRoad={ _nearestRoad=objNull; _closestDistanceToRoad=0; _searchPos = _this select 0; _minDistance = _this select 1; _maxDistance = _this select 2; _closestDistanceToRoad = _maxDistance; { if ((_searchPos distance _x < _maxDistance) && (_searchPos distance _x > _minDistance)) then { _distanceToRoad = _searchPos distance _x; if (_distanceToRoad < _closestDistanceToRoad) then { _nearestRoad = _x; _closestDistanceToRoad = _distanceToRoad; }; }; } forEach (_searchPos nearRoads _maxDistance); _nearestRoad; }; // Function creates a random convoy intercept mission // Randomizes starting and ending locations // Uses semaphore to prevent multiple missions at the same time // Creates task for player to intercept convoy // Create triggers that monitors convoy death or convoy completed // reset multi-mission semaphore // clean up all waypoints // fail task on convoy complete // succeed task on convoy death // Creates convoy units in a group // Creates convoy waypoint at destination // Creates start/end markers // Cleans up markers, group and task on mission success/failure fSpawnEnemyConvoy = { if (convoyMissionAssigned) exitWith { hint "Convoy mission is already assigned. Complete the assigned mission."; }; _randomStartDistanceX = random 1000 - (1000/2); _randomStartDistanceY = random 1000 - (1000/2); _startPositionMin = 1500; _startPositionMax = 3000; _endPositionMin = 2000; _endPositionMax = 4000; convoyMissionAssigned = true; convoyMarkers = []; _playerUnit = player; _searchPos = getPos _playerUnit; // randomize the starting location +/- 100m _searchPos = [(_searchPos select 0) + (_randomStartDistanceX), (_searchPos select 1) + (_randomStartDistanceY), _searchPos select 2]; _startRoad = [_searchPos, _startPositionMin, _startPositionMax] call fGetNearestRoad; mkrConvoyStart = createMarker ["convoyMarkerStart", getPos _startRoad]; mkrConvoyStart setMarkerText "Convoy start"; mkrConvoyStart setMarkerType "Start"; mkrConvoyStart setMarkerColor "ColorRed"; mkrConvoyStart setMarkerAlpha 0.5; //"Flag", "Flag1", "Dot", "Destroy", "Start", "End", "Warning", "Join", "Pickup", "Unknown", "Marker", "Arrow" or "Empty". //markerName setMarkerPos pos _searchPos = getMarkerPos mkrConvoyStart; _endRoad = [_searchPos, _endPositionMin, _endPositionMax] call fGetNearestRoad; mkrConvoyEnd = createMarker ["convoyMarkerEnd", getPos _endRoad]; mkrConvoyEnd setMarkerText "Convoy End"; mkrConvoyEnd setMarkerType "End"; mkrConvoyEnd setMarkerColor "ColorRed"; mkrConvoyEnd setMarkerAlpha 0.5; // get the convoy pointing towards the ending marker //_startAngle = [getMarkerPos mkrConvoyStart, getMarkerPos mkrConvoyEnd] call fGetAngleOfTwoPoints; _startPos = getMarkerPos mkrConvoyStart; _endPos = getMarkerPos mkrConvoyEnd; _preferredAngle = [_startPos, _endPos] call BIS_fnc_DirTo; _startAngle = [_startRoad, _preferredAngle] call fGetRoadHeading; _startingPositions = [_startPos, _startAngle, -10, 10] call fGetArrayOfPointsOnRoadFromAngle; _spawn = [_startingPositions select 0, _startAngle, "Offroad_DSHKM_INS", EAST] call BIS_fnc_spawnVehicle; unit1 = _spawn select 0; convoyGroup = _spawn select 2; _wp = convoyGroup addWaypoint [_endPos, 0]; _wp setWaypointType "SAD"; _wp setWaypointBehaviour "SAFE"; convoyGroup setFormation "COLUMN"; // BUG: change behavior of entire group to alert on any awareness change/gunfire //create the rest of the group with delays - to let the lead element get rolling [_startingPositions, _startAngle] spawn { _startingPositions = _this select 0; _startAngle = _this select 1; sleep 6; _retVal = [_startingPositions select 1, _startAngle, "Ural_INS", convoyGroup] call BIS_fnc_spawnVehicle; _transport = _retVal select 0; groupConvoyEscort = [_startingPositions select 3, EAST, (configFile >> "CfgGroups" >> "East" >> "INS" >> "Infantry" >> "INS_InfSquad_Weapons"),[],[],[0.8,1],[],[12,1],_startAngle] call BIS_fnc_spawnGroup; {_x moveInCargo _transport; sleep 0.05;} forEach units groupConvoyEscort; sleep 10; [_startingPositions select 2, _startAngle, "UralRefuel_INS", convoyGroup] call BIS_fnc_spawnVehicle; sleep 6; [_startingPositions select 3, _startAngle, "Pickup_PK_Ins", convoyGroup] call BIS_fnc_spawnVehicle; sleep 6; [_startingPositions select 4, _startAngle, "UAZ_AGS30_INS", convoyGroup] call BIS_fnc_spawnVehicle; sleep 6; [_startingPositions select 5, _startAngle, "TT650_Ins", convoyGroup] call BIS_fnc_spawnVehicle; // we do this to improve their driving ability (hopefully) {_x setSkill 1} forEach units convoyGroup; hint "Convoy is enroute.."; }; // create task for player convoyTask = _playerUnit createSimpleTask ["InterceptConvoy"]; convoyTask setSimpleTaskDescription ["We have intel of an armed Opfor convoy. Intercept and destroy it before it reaches the destination.", "Destroy Convoy", "Destroy Convoy"]; convoyTask setTaskState "Assigned"; ["HQ here. We have intel of an armed Opfor convoy. Intercept and destroy it before it reaches the destination."] call fHQMsg; // create trigger to detect convoy arrival to destination trgDetectConvoyArrived = createTrigger ["EmptyDetector", _endPos]; trgDetectConvoyArrived setTriggerArea [100,100,0,false]; trgDetectConvoyArrived setTriggerActivation ["EAST", "PRESENT", true]; trgDetectConvoyArrived setTriggerStatements ["{vehicle _x in thislist} forEach units convoyGroup;", "[false] call fCleanUpConvoyMission;", ""]; // create trigger to detect convoy destruction trgDetectConvoyDestroyed = createTrigger ["EmptyDetector", _endPos]; trgDetectConvoyDestroyed setTriggerArea [0,0,0,false]; trgDetectConvoyDestroyed setTriggerActivation ["NONE", "PRESENT", true]; trgDetectConvoyDestroyed setTriggerStatements ["({alive _x} count units convoyGroup) < 1;", "[true] call fCleanUpConvoyMission;", ""]; }; // removes all the markers and triggers for the mission // param1: "Succeeded"/"Failed" -- sets task to success or failure fCleanUpConvoyMission = { _taskState = _this select 0; if !(convoyMissionAssigned) exitWith {}; convoyMissionAssigned = false; if (_taskState) then { player sideChat "HQ, Alpha here. All convoy elements have been destroyed."; ["HQ here. Roger that, nice work."] call fHQMsg; convoyTask setTaskState "Succeeded"; } else { ["HQ here. Intel reports that convoy has arrived at destination. Mission failed."] call fHQMsg; convoyTask setTaskState "Failed"; {deleteVehicle vehicle _x; deleteVehicle _x;} forEach units convoyGroup; }; trgDetectConvoyArrived = objNull; trgDetectConvoyDestroyed = objNull; deleteMarker mkrConvoyEnd; deleteMarker mkrConvoyStart; };