Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions addons/ai/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
PREP(garrison);
PREP(throwGrenade);
PREP(unGarrison);
3 changes: 2 additions & 1 deletion addons/ai/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "script_component.hpp"

[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler;
[QGVAR(throwGrenade), LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler;
[QGVAR(unGarrison), LINKFUNC(unGarrison)] call CBA_fnc_addEventHandler;
88 changes: 88 additions & 0 deletions addons/ai/functions/fnc_throwGrenade.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include "script_component.hpp"
/*
* Author: mharis001
* Makes the unit throw a grenade at the given position.
* Must be called where the unit is local.
*
* Arguments:
* 0: Unit <OBJECT>
* 1: Grenade Muzzle <STRING>
* 2: Position ASL <ARRAY>
*
* Return Value:
* None
*
* Example:
* [_unit, "HandGrenadeMuzzle", [0, 0, 0]] call zen_ai_fnc_throwGrenade
*
* Public: No
*/

#define AIMING_TIMEOUT 10
#define INITIAL_DELAY 0.5
#define CLEANUP_DELAY 1.5

#define TOLERANCE_TIME 2
#define MIN_TOLERANCE 10
#define MAX_TOLERANCE 45

params ["_unit", "_muzzle", "_position"];

// Create a helper object for the unit to target
private _helper = "Land_HelipadEmpty_F" createVehicleLocal [0, 0, 0];
_helper setPosASL _position;

// Make the unit target the helper object
_unit reveal _helper;
_unit doWatch _helper;
_unit doTarget _helper;

// Disable AI intelligence until unit throws the grenade
// Also interrupts a unit's movement to a waypoint, forcing them to stop
_unit disableAI "FSM";
_unit disableAI "PATH";

// Wait until the unit is aiming at the helper object before throwing the grenade
// Initial delay helps prevent weird issue when the unit is moving to a waypoint and the helper is directly in front of it
[{
_this set [2, CBA_missionTime];

[
{
params ["_unit", "_helper", "_startTime"];

if (!alive _unit) exitWith {false};

// Check that the unit is aiming at the helper, increase tolerance as more time passes
private _direction = _unit getRelDir _helper;
private _tolerance = linearConversion [0, TOLERANCE_TIME, CBA_missionTime - _startTime, MIN_TOLERANCE, MAX_TOLERANCE, true];

_direction <= _tolerance || {_direction >= 360 - _tolerance}
},
{
params ["_unit", "_helper", "", "_muzzle"];

if (alive _unit) then {
[_unit, _muzzle] call BIS_fnc_fire;

// Reset AI intelligence and targeting
[{
params ["_unit"];

_unit enableAI "FSM";
_unit enableAI "PATH";
_unit doWatch objNull;
}, _unit, CLEANUP_DELAY] call CBA_fnc_waitAndExecute;
};

deleteVehicle _helper;
},
_this,
AIMING_TIMEOUT,
{
params ["", "_helper"];

deleteVehicle _helper;
}
] call CBA_fnc_waitUntilAndExecute;
}, [_unit, _helper, 0, _muzzle], INITIAL_DELAY] call CBA_fnc_waitAndExecute;
14 changes: 12 additions & 2 deletions addons/context_actions/CfgContext.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
class EGVAR(context_menu,actions) {
class ThrowGrenade {
displayName = CSTRING(ThrowGrenade);
icon = QPATHTOF(ui\grenade_ca.paa);
priority = -50;
insertChildren = QUOTE([_selectedObjects] call FUNC(getGrenadeActions));
};
class Formation {
displayName = "$STR_3DEN_Group_Attribute_Formation_displayName";
icon = "\a3\3den\data\displays\display3den\entitymenu\movetoformation_ca.paa";
condition = QUOTE(!(_selectedGroups isEqualTo []));
priority = -60;
class Wedge {
displayName = "$STR_wedge";
icon = "\a3\Ui_F_Curator\Data\RscCommon\RscAttributeFormation\wedge_ca.paa";
Expand Down Expand Up @@ -61,6 +68,7 @@ class EGVAR(context_menu,actions) {
class Behaviour {
displayName = "$STR_3DEN_Group_Attribute_Behaviour_displayName";
condition = QUOTE(!(_selectedGroups isEqualTo []));
priority = -61;
class Careless {
displayName = "$STR_3DEN_Attributes_Behaviour_Careless_text";
icon = QPATHTOF(ui\careless_ca.paa);
Expand Down Expand Up @@ -94,6 +102,7 @@ class EGVAR(context_menu,actions) {
class Speed {
displayName = "$STR_HC_Menu_Speed";
condition = QUOTE(!(_selectedGroups isEqualTo []));
priority = -62;
class Limited {
displayName = "$STR_speed_limited";
icon = "\a3\Ui_F_Curator\Data\RscCommon\RscAttributeSpeedMode\limited_ca.paa";
Expand All @@ -116,6 +125,7 @@ class EGVAR(context_menu,actions) {
class Stance {
displayName = "$STR_A3_RscAttributeUnitPos_Title";
condition = QUOTE(_selectedObjects findIf {_x isKindOf 'CAManBase' && {!isPlayer _x}} > -1);
priority = -63;
class Auto {
displayName = "$STR_A3_RscAttributeUnitPos_Auto_tooltip";
icon = QPATHTOF(ui\default_ca.paa);
Expand All @@ -141,6 +151,7 @@ class EGVAR(context_menu,actions) {
displayName = ECSTRING(modules,ModuleHeal);
icon = QPATHTOF(ui\medical_cross_ca.paa);
condition = QUOTE(_selectedObjects findIf {crew _x findIf {_x isKindOf 'CAManBase' && {alive _x}} != -1} != -1);
priority = -70;
class All {
displayName = ECSTRING(common,All);
statement = QUOTE([ARR_2(_selectedObjects,HEAL_MODE_ALL)] call FUNC(healUnits));
Expand All @@ -158,7 +169,6 @@ class EGVAR(context_menu,actions) {
statement = QUOTE([ARR_2(_selectedObjects,HEAL_MODE_PLAYERS)] call FUNC(healUnits));
priority = 1;
};
priority = -70;
};
class VehicleLogistics {
displayName = CSTRING(VehicleLogistics);
Expand All @@ -179,6 +189,7 @@ class EGVAR(context_menu,actions) {
} \
} != -1 \
);
priority = -71;
class Repair {
displayName = CSTRING(Repair);
icon = "\A3\ui_f\data\igui\cfg\simpleTasks\types\repair_ca.paa";
Expand Down Expand Up @@ -206,7 +217,6 @@ class EGVAR(context_menu,actions) {
statement = QUOTE(_selectedObjects call FUNC(refuelVehicles));
priority = 1;
};
priority = -71;
};
class Loadout {
displayName = "$STR_3den_display3den_entitymenu_arsenal_text";
Expand Down
3 changes: 3 additions & 0 deletions addons/context_actions/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
PREP(compileGrenades);
PREP(getGrenadeActions);
PREP(healUnits);
PREP(rearmVehicles);
PREP(refuelVehicles);
PREP(repairVehicles);
PREP(selectThrowPos);
PREP(setBehaviour);
PREP(setFormation);
PREP(setSpeed);
Expand Down
2 changes: 2 additions & 0 deletions addons/context_actions/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

call FUNC(compileGrenades);

ADDON = true;
35 changes: 35 additions & 0 deletions addons/context_actions/functions/fnc_compileGrenades.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "script_component.hpp"
/*
* Author: mharis001
* Compiles a list of all throwable grenades.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call zen_context_actions_fnc_compileGrenades
*
* Public: No
*/

GVAR(grenades) = [] call CBA_fnc_createNamespace;
GVAR(grenadesList) = []; // For fast filtering of non-grenade magazines

private _cfgWeapons = configFile >> "CfgWeapons";
private _cfgMagazines = configFile >> "CfgMagazines";

{
private _muzzle = _x;

{
private _config = _cfgMagazines >> _x;
private _displayName = getText (_config >> "displayName");
private _picture = getText (_config >> "picture");

GVAR(grenades) setVariable [_x, [_displayName, _picture, _x, _muzzle]];
GVAR(grenadesList) pushBackUnique _x;
} forEach getArray (_cfgWeapons >> "Throw" >> _muzzle >> "magazines");
} forEach getArray (_cfgWeapons >> "Throw" >> "muzzles");
49 changes: 49 additions & 0 deletions addons/context_actions/functions/fnc_getGrenadeActions.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "script_component.hpp"
/*
* Author: mharis001
* Returns children actions based on grenades in selected AI's inventories.
*
* Arguments:
* 0: Selected Objects <ARRAY>
*
* Return Value:
* Actions <ARRAY>
*
* Example:
* [[_unit1, _unit2]] call zen_context_actions_fnc_getGrenadeActions
*
* Public: No
*/

params ["_objects"];

// Get all magazines in the inventories of on foot AI
private _magazines = [];
{
if (!isPlayer _x && {vehicle _x == _x}) then {
_magazines append magazines _x;
};
} forEach _objects;

// Filter out non-grenade magazines, sort alphabetically by display name
private _grenades = _magazines arrayIntersect GVAR(grenadesList) apply {GVAR(grenades) getVariable _x};
_grenades sort true;

private _actions = [];

{
_x params ["_displayName", "_picture", "_magazine", "_muzzle"];

private _action = [
format [QGVAR(%1), _forEachIndex],
_displayName,
_picture,
{[_selectedObjects, _args] call FUNC(selectThrowPos)},
{true},
[_magazine, _muzzle]
] call EFUNC(context_menu,createAction);

_actions pushBack [_action, [], 0];
} forEach _grenades;

_actions
45 changes: 45 additions & 0 deletions addons/context_actions/functions/fnc_selectThrowPos.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "script_component.hpp"
/*
* Author: mharis001
* Allows Zeus to select a position to make AI throw grenades at.
*
* Arguments:
* 0: Selected Objects <ARRAY>
* 1: Arguments <ARRAY>
*
* Return Value:
* None
*
* Example:
* [[_unit1, _unit2], ["HandGrenade", "HandGrenadeMuzzle"]] call zen_context_actions_fnc_selectThrowPos
*
* Public: No
*/

#define MAX_DISTANCE 50

params ["_selectedObjects", "_args"];
_args params ["_magazine", "_muzzle"];

// Get AI units that are alive, on foot, and have the selected grenade type
private _units = _selectedObjects select {
alive _x
&& {!isPlayer _x}
&& {_x isKindOf "CAManBase"}
&& {vehicle _x == _x}
&& {_magazine in magazines _x}
};

private _text = format [localize LSTRING(ThrowX), getText (configFile >> "CfgMagazines" >> _magazine >> "displayName")];

[_units, {
params ["_successful", "_units", "_position", "_muzzle"];

if (!_successful) exitWith {};

{
if (_x distance2D _position < MAX_DISTANCE) then {
[QEGVAR(ai,throwGrenade), [_x, _muzzle, _position], _x] call CBA_fnc_targetEvent;
};
} forEach _units;
}, _muzzle, _text] call EFUNC(common,getTargetPos);
6 changes: 6 additions & 0 deletions addons/context_actions/stringtable.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ZEN">
<Package name="Context_Actions">
<Key ID="STR_ZEN_Context_Actions_ThrowGrenade">
<English>Throw Grenade</English>
</Key>
<Key ID="STR_ZEN_Context_Actions_ThrowX">
<English>Throw %1</English>
</Key>
<Key ID="STR_ZEN_Context_Actions_EditInventory">
<English>Edit Inventory</English>
<Russian>Редактировать снаряжение</Russian>
Expand Down
Binary file added addons/context_actions/ui/grenade_ca.paa
Binary file not shown.