Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve anti-vehicle responses #369

Merged
merged 11 commits into from
Jul 7, 2024
2 changes: 1 addition & 1 deletion addons/danger/functions/fnc_tacticsAssess.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ if !(_enemies isEqualTo [] || {_unitCount < random 4}) then {
};

// soft vehicle response
private _hasAT = ((units _unit) findIf {(secondaryWeapon _x) isNotEqualTo ""}) isNotEqualTo -1;
private _hasAT = ([_group, false, true, false, true] call EFUNC(main,getLauncherUnits)) isNotEqualTo [];
private _vehicleTarget = _enemies findIf {
_hasAT
&& {_unit distance2D _x < RANGE_NEAR}
Expand Down
16 changes: 9 additions & 7 deletions addons/danger/functions/fnc_tacticsHide.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -100,26 +100,28 @@ _units doWatch objNull;
// disperse and hide unit ~ notice that cover is added as building positions nkenny
[_units, _target, _cover] call EFUNC(main,doGroupHide);

// find launcher and armour
private _launchers = _units select {(secondaryWeapon _x) isNotEqualTo ""};
// find launcher units
private _launchersAT = [_group, false, true, false, true] call EFUNC(main,getLauncherUnits);
private _launchersAA = [_group, false, false, true, false] call EFUNC(main,getLauncherUnits);

// find enemy air/tanks
// find enemy vehicles
private _enemies = _unit targets [true, 600, [], 0, _target];
private _tankAir = _enemies findIf {(vehicle _x) isKindOf "Tank" || {(vehicle _x) isKindOf "Air"}};

if (_antiTank && { _tankAir != -1 } && { _launchers isNotEqualTo [] }) then {
if (_antiTank && { _tankAir != -1 } && { _launchersAT isNotEqualTo [] || (_launchersAA isNotEqualTo []) }) then {
private _targetVehicle = vehicle (_enemies select _tankAir);
{
// launcher units target air/tank
_x setCombatMode "RED";
_x commandTarget (_enemies select _tankAir);
_x commandTarget _targetVehicle;

// extra impetuous to select launcher
_x selectWeapon (secondaryWeapon _x);
_x setUnitPosWeak "MIDDLE";
} forEach _launchers;
} forEach ([_launchersAA, _launchersAT] select (_targetVehicle isKindOf "Tank"));

// extra aggression from unit
_unit doFire (_enemies select _tankAir);
_unit doFire _targetVehicle;
};

// debug
Expand Down
1 change: 1 addition & 0 deletions addons/main/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ PREP(doAnimation);
PREP(doCallout);
PREP(doGesture);
PREP(doShareInformation);
PREP(getLauncherUnits);
PREP(getShareInformationParams);
PREP(shouldSuppressPosition);

Expand Down
72 changes: 72 additions & 0 deletions addons/main/functions/fnc_getLauncherUnits.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "script_component.hpp"
/*
* Author: ThomasAngel
* Gets all units from a group that have launchers.
* Things like AP launchers, flares etc will not count, -
* launcher must be capable of destroying at least some vehicle.
*
* Checking through the submunitions might improve mod compatibility,
* but only if the AI actually accounts for submunitions when evaluating -
* whether to engage or not. As of writing, this is unknown.
*
* Disposable launchers get mostly ignored, AI doesn't seem to even use them.
*
* Arguments:
* 0: Group to search in <GROUP>
* 1: Check through submunitions <BOOLEAN>
*
* Return Value:
* Array - units with launchers
*
* Example:
* [group bob] call lambs_main_fnc_getLauncherUnits;
*
* Public: Yes
*/

#define LIGHT_VEHICLE 128
#define AIR_VEHICLE 256
#define HEAVY_VEHICLE 512

params [
["_group", grpNull, [grpNull]],
["_checkSubmunition", false, [false]],
["_offensiveVeh", true, [true]],
["_offensiveAir", true, [true]],
["_offensiveArmor", true, [true]]
];

rekterakathom marked this conversation as resolved.
Show resolved Hide resolved
private _suitableUnits = [];
{
if ((secondaryWeapon _x) isEqualTo "") then {continue};
private _currentUnit = _x;

private _unitsMagazines = (magazines _currentUnit) + (secondaryWeaponMagazine _currentUnit);
{
if (
(_offensiveVeh && ([_x, LIGHT_VEHICLE] call lambs_main_fnc_checkMagazineAiUsageFlags))
|| {_offensiveAir && ([_x, AIR_VEHICLE] call lambs_main_fnc_checkMagazineAiUsageFlags)}
|| {_offensiveArmor && ([_x, HEAVY_VEHICLE] call lambs_main_fnc_checkMagazineAiUsageFlags)}
) exitWith {_suitableUnits pushBackUnique _currentUnit};
rekterakathom marked this conversation as resolved.
Show resolved Hide resolved

// Optionally go through submunitions. More info in header.
if !(_checkSubmunition) then {continue}; // Invert & continue to reduce indentation

// Can't use checkMagazineAiUsageFlags for submunitions
private _mainAmmo = getText (configFile >> "cfgMagazines" >> _x >> "ammo");
private _submunition = getText (configFile >> "cfgAmmo" >> _mainAmmo >> "submunitionAmmo");
rekterakathom marked this conversation as resolved.
Show resolved Hide resolved
if (_submunition isEqualTo "") then {continue};
private _submunitionFlags = getText (configFile >> "cfgAmmo" >> _submunition >> "aiAmmoUsageFlags");
rekterakathom marked this conversation as resolved.
Show resolved Hide resolved
rekterakathom marked this conversation as resolved.
Show resolved Hide resolved

if (
(_offensiveVeh && (QUOTE(LIGHT_VEHICLE) in _submunitionFlags))
|| {_offensiveAir && (QUOTE(AIR_VEHICLE) in _submunitionFlags)}
|| {_offensiveArmor && (QUOTE(HEAVY_VEHICLE) in _submunitionFlags)}
) exitWith {_suitableUnits pushBackUnique _currentUnit};
} forEachReversed _unitsMagazines;
// We iterate back to front for performance, because _unitsMagazines is structured -
// as follows: uniform magazines -> vest magazines -> backpack magazines, and -
// launcher ammo is usually in the backpack. This is a ~3-4x speedup.
} forEach (units _group);

_suitableUnits
3 changes: 2 additions & 1 deletion addons/wp/functions/fnc_taskRush.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,10 @@ private _fnc_rushOrders = {
};

// Tank -- hide or ready AT
private _launcherUnits = [_group, false] call EFUNC(main,getLauncherUnits);
if ((_distance < 80) && {(vehicle _target) isKindOf "Tank"}) exitWith {
{
if ((secondaryWeapon _x) isNotEqualTo "") then {
if (_x in _launcherUnits) then {
_x setUnitPos "MIDDLE";
_x selectWeapon (secondaryWeapon _x);
} else {
Expand Down
Loading