Code:
/*
Author: Karel Moricky
Description:
Waypoint - Attach sling load
Parameter(s):
(set by waypoint)
Returns:
Nothing
*/
_wpFunction = "BIS_fnc_wpSlingloadAttach";
_wpName = localize "STR_HSIM_BIS_fnc_wpSlingLoadAttach_Name";
#include "variableSettings.hpp"
_delay = 0.1;
_posCounter = 0;
_forced = false;
_posLimit = [_params,0,-1,[0,true]] call bis_fnc_param;
_failCode = [_params,1,{},[{}]] call bis_fnc_param;
_weight = [_params,2,-1,[0]] call bis_fnc_param;
_forced = false;
_PIP = false;
if (typename _posLimit == typename true) then {
_forced = _posLimit;
_posLimit = -1;
};
if (_posLimit < 0) then {_posLimit = _delay};
//--- No target - Mission Accomplished
if (isnull _target) exitwith {};
//--- Smaller default completion radius
if (waypointcompletionradius _wp == 0 && _mode != 2) then {_completionRadius = 42};
_bboxZ = boundingbox _veh select 1 select 2;
//////////////////////////////////////////////////////////////////////////////////////////
//--- Prepared
_checkDistance = {
_veh = vehicle _x;
if (_veh iskindof "Helicopter") then {
if (isnil {_veh getvariable "BIS_slingload_attach"}) then {
_limitDistance = if (isplayer driver _veh) then {_completionRadius} else {100};
//--- Hook point on helicopter
_vehPos = _veh selectionposition "slingload0";
_vehPos = if (_vehPos distance [0,0,0] > 0) then {
_veh modeltoworld _vehPos;
} else {
_vehBboxZ = boundingbox _veh select 0 select 2;
_veh modeltoworld [0,0,_vehBboxZ];
};
//--- Hook point on target
_targetPos = _target selectionposition "slingload0";
_targetPos = if (_targetPos distance [0,0,0] > 0) then {
_target modeltoworld _vehPos;
} else {
_targetBboxZ = boundingbox _target select 1 select 2;
_target modeltoworld [0,0,_targetBboxZ];
};
//--- Generic Sentences
if (_vehPos distance _targetPos < _limitDistance * 10 && !_forced) then {
if !(_PIP) then {
if !(_forced) then {
{
_veh = vehicle _x;
if (isplayer driver _veh && isplayer _x) then {
_camPos = _veh selectionposition "slingload0";
_camPos set [2,(_camPos select 2) - 0.2];
["rendertarget0",[[_veh,_camPos],_target],_veh,false] call bis_fnc_pip;
"rendertarget0" setPiPEffect [3, 1.0, 1.0, 1.5, 0.0, [0, 0, 0, 0], [1, 1, 1, 0], [1,1,1,0]];
};
} foreach units _group;
};
_PIP = true;
};
if (abs ((_vehPos select 2) - (_targetPos select 2)) < 50) then {
//--- Direction
_dirto = [_veh,_targetPos] call bis_fnc_relativedirto;
_dirto = floor (((_dirto + 45 + 360) % 360) / 90);
[
[
"FeedbackFlightNegativeDirectionsForward",
"FeedbackFlightNegativeDirectionsRight",
"FeedbackFlightNegativeDirectionsBackward",
"FeedbackFlightNegativeDirectionsLeft"
] select _dirto
] call bis_fnc_genericSentence;
} else {
//--- Altitude
if ((_vehPos select 2) > (_targetPos select 2)) then {
["FeedbackFlightNegativeHeightTooHigh"] call bis_fnc_genericSentence;
} else {
["FeedbackFlightNegativeHeightTooLow"] call bis_fnc_genericSentence;
};
};
};
_vehPos distance _targetPos < _limitDistance
||
_forced
} else {
false
};
} else {
false
};
};
//////////////////////////////////////////////////////////////////////////////////////////
//--- Condition
waituntil {
_time = time;
waituntil {time - _time > _delay};
if (call _isExpired || isnull _group || isnull _target) exitwith {};
//--- AI Move
{
_veh = vehicle _x;
if (_veh iskindof "Helicopter" && !isplayer driver _veh) then {
_expected = expecteddestination _veh select 0;
if (_expected distance _target > 50) then {
_veh domove position _target;
if (_veh distance _target < 100) then {
_veh flyinheight 20;
_veh setspeedmode "limited";
};
};
};
if (call _checkDistance) then {
_posCounter = _posCounter + (time - _time);
if !(_forced) then {
hintsilent format [(localize "STR_HSIM_BIS_FNC_WPSLINGLOAD_HINT") + " %1%2",round ((_posCounter / _posLimit) * 100) min 100,"%"];
};
} else {
_posCounter = 0
};
} foreach units _group;
(call _condition && _posCounter >= _posLimit) || _forced
};
if (call _isExpired || isnull _group || isnull _target) exitwith {};
//////////////////////////////////////////////////////////////////////////////////////////
//--- Load
//--- Select suitable helicopters
_heli = if (_mode == 2) then {
_veh
} else {
_listHeli = [];
{
_veh = vehicle _x;
if (call _checkDistance) then {
if !(_veh in _listHeli) then {_listHeli = _listHeli + [_veh]};
};
} foreach units _group;
//--- Select nearest helicopter
[_listHeli,_target] call BIS_fnc_nearestPosition;
};
//--- Attach
//--- Calculate rope length (default is sum of boundingbox heights of heli and target)
//_ropeLengthDefault = (sizeof typeof _target) / 2 + (sizeof typeof _heli) / 2;
_bboxHeli = boundingbox _heli;
_sizeHeli = abs((_bboxHeli select 0) select 2) + abs((_bboxHeli select 1) select 2);
_bboxTarget = boundingbox _target;
_sizeTarget = abs((_bboxTarget select 0) select 2) + abs((_bboxTarget select 1) select 2);
_ropeLengthDefault = _sizeHeli + _sizeTarget;
_ropeLength = if (_forced || true) then {
_ropeLengthDefault
} else {
(_heli distance _target) max _ropeLengthDefault
};
//--- Get connection points
_targetPos = _target selectionposition "slingload0";
_targetPos = if (_targetPos distance [0,0,0] > 0) then {
"slingload1"
} else {
_targetBboxZ = _bboxTarget select 1 select 2;
[0,0,_targetBboxZ];
};
//--- Connect
_ropeSegments = 10;
_ropeSegmentsLength = (_ropeLength / _ropeSegments);
_rope = ropeCreate [_heli,"slingload0",_target,_targetPos,_ropeSegments,_ropeLength];
//--- Event handlers
_ropeEHcustom = _heli addeventhandler [
"RopeBreak",
_failCode
];
_ropeEH = _heli addeventhandler [
"RopeBreak",
{
_this spawn {
_heli = _this select 0;
_rope = _this select 1;
_cargo = _heli getvariable ["BIS_slingload_attach",objnull];
SLINGLOAD_CLEANUP
sleep 5;
ropedestroy _rope;
//--- Mark the cargo as lost
_cargo setvariable ["BIS_slingload_lost",true];
};
}
];
//--- Sect custom weight
ropeSetCargoMass [_rope,_target,_weight];
//--- Store attached object variables
_heli setvariable ["BIS_slingload_attach",_target];
_heli setvariable ["BIS_slingload_rope",_rope];
_heli setvariable ["BIS_slingload_ropeEH",_ropeEH];
_heli setvariable ["BIS_slingload_ropeEHcustom",_ropeEH];
_target setvariable ["BIS_slingload_attach",_heli];
//--- Remove PIP
["rendertarget0"] call BIS_fnc_PIP;
200 call _fnc_addRating;