diff --git a/addons/aircraft/functions/fnc_droneAddActions.sqf b/addons/aircraft/functions/fnc_droneAddActions.sqf index 38ca53e4c6..895004f0e9 100644 --- a/addons/aircraft/functions/fnc_droneAddActions.sqf +++ b/addons/aircraft/functions/fnc_droneAddActions.sqf @@ -22,7 +22,7 @@ if (!alive _vehicle) exitWith {}; if (_vehicle getVariable [QGVAR(droneActionsAdded), false]) exitWith {}; _vehicle setVariable [QGVAR(droneActionsAdded), true]; -// move to location +// Move to location private _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} @@ -37,14 +37,63 @@ private _action = [QGVAR(droneSetWaypointMove), localize "$STR_AC_MOVE", "\a3\3DEN\Data\CfgWaypoints\Move_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +// Follow unit/vehicle at turret location +_condition = { + params ["_vehicle"]; + private _target = cursorTarget; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {!isNull _target} && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1} +}; +_statement = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; + [QGVAR(droneSetWaypoint), [_vehicle, _group, _pos, "FOLLOW", cursorTarget], _group] call CBA_fnc_targetEvent; + private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0]; + [[LLSTRING(DroneFollowHint), _followDistance], 3] call EFUNC(common,displayTextStructured); +}; +_action = [QGVAR(droneSetWaypointFollow), localize "$STR_AC_FOLLOW", "\a3\3DEN\Data\CfgWaypoints\Follow_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); +[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + +// Set drone follow distance +_condition = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _index = (currentWaypoint _group) min count waypoints _group; + private _waypoint = [_group, _index]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {(waypointType _waypoint) == "HOLD"} +}; +_statement = { + params ["_vehicle", "", "_value"]; + _vehicle setVariable [QGVAR(wpFollowDistance), _value]; + [[LLSTRING(DroneFollowHint), _value], 3] call EFUNC(common,displayTextStructured); +}; +_action = [QGVAR(droneSetFollowDistance), LLSTRING(DroneFollowDistance), "", {}, _condition] call EFUNC(interact_menu,createAction); +private _base = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +private _followDistances = if (_vehicle isKindOf "Car_F") then { + [0, 25, 50, 100, 200] +} else { + [0, 100, 200, 300, 400, 500] +}; +{ + _action = [ + QGVAR(droneSetFollowDistance_) + str _x, + str _x, + "", + _statement, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction); + [_vehicle, 1, _base, _action] call EFUNC(interact_menu,addActionToObject); +} forEach _followDistances; if (_vehicle isKindOf "Air") then { - // loiter at location + // Loiter at location _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} }; - _statement = { + _statement = { params ["_vehicle"]; private _group = group driver _vehicle; private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; @@ -55,7 +104,7 @@ if (_vehicle isKindOf "Air") then { [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); - // set height + // Set height _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} @@ -74,7 +123,7 @@ if (_vehicle isKindOf "Air") then { } forEach [20, 50, 200, 500, 2000]; - // set loiter radius + // Set loiter radius _condition = { params ["_vehicle"]; private _group = group driver _vehicle; @@ -97,7 +146,7 @@ if (_vehicle isKindOf "Air") then { } forEach [500, 750, 1000, 1250, 1500]; - // set loiter direction + // Set loiter direction _condition = { params ["_vehicle", "", "_args"]; private _group = group driver _vehicle; diff --git a/addons/aircraft/functions/fnc_droneSetWaypoint.sqf b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf index 5ffbbae825..953b99a357 100644 --- a/addons/aircraft/functions/fnc_droneSetWaypoint.sqf +++ b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf @@ -8,6 +8,7 @@ * 1: Group * 2: Pos 2D * 3: Type + * 4: Target to follow (default: objNull) * * Return Value: * None @@ -18,7 +19,7 @@ * Public: No */ -params ["_vehicle", "_group", "_pos", "_type"]; +params ["_vehicle", "_group", "_pos", "_type", ["_target", objNull]]; TRACE_4("droneSetWaypoint",_vehicle,_group,_pos,_type); private _index = (currentWaypoint _group) min count waypoints _group; @@ -34,9 +35,34 @@ _pos set [ [0, _currentHeight] select (_currentHeight >= 50) ]; -// [_group] call CBA_fnc_clearWaypoints; _waypoint = _group addWaypoint [_pos, 0]; -_waypoint setWaypointType _type; +// The Vanilla "FOLLOW"-type waypoint is not used directly, due to 2 main issues (as of v2.16): +// - It does not work at all for UGVs, which is a known issue https://feedback.bistudio.com/T126283; +// - No clear scripting way was found to mimic the UAV Terminal's "Follow Distance" functionality; +// Instead, the solution for both UAV and UGV following consists of a CBA PFH that moves a "HOLD"-type Waypoint every 3 seconds. +// Either on the target itself, or on the Drone's current position if the target is within the desired follow distance. +if (_type == "FOLLOW" && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1}) then { + _waypoint setWaypointType "HOLD"; + [{ + params ["_args", "_handle"]; + _args params ["_vehicle", "_group", "_waypoint", "_target"]; + + if ( // Abort PFH if a new waypoint is created via UAV Terminal or ACE Interaction + _waypoint select 1 != currentWaypoint _group || + {!alive _vehicle} || {isNull _target} + ) exitWith { + deleteWaypoint _waypoint; + [_handle] call CBA_fnc_removePerFrameHandler; + }; + + private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0]; + if ((_vehicle distance2D _target) < _followDistance) then { + _waypoint setWaypointPosition [getPosASL _vehicle, -1]; + } else { + _waypoint setWaypointPosition [getPosASL _target, -1]; + }; + }, 3, [_vehicle, _group, _waypoint, _target]] call CBA_fnc_addPerFrameHandler; +}; TRACE_3("",_currentHeight,_currentLoiterRadius,_currentLoiterType); if (_currentHeight > 1) then { _vehicle flyInHeight _currentHeight; }; diff --git a/addons/aircraft/stringtable.xml b/addons/aircraft/stringtable.xml index c0cef87756..a60706aad3 100644 --- a/addons/aircraft/stringtable.xml +++ b/addons/aircraft/stringtable.xml @@ -177,5 +177,15 @@ 30мм СБ 5:1 30mm CM 5:1 + + Follow Distance + Distanza di seguimento + Folge-Entfernung + + + Following unit within %1m + Seguendo unità entro %1m + Folgt Einheit bis zu %1m + diff --git a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf index 3e7ce4f15c..925178d642 100644 --- a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf @@ -18,4 +18,4 @@ params ["_caller", "_target"]; -("ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} +(alive _target) && {"ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))} && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4}