From 981a8ea3521f5b981f13265bc81e6764be0c8f72 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 1 Sep 2022 13:38:22 -0500 Subject: [PATCH] Hunter Killer (Commander Override) (#8496) * Hunter Killer (Commander Override) - Initial Demo * Just do a one-time slew * Update fnc_eachFrame.sqf * Update addons/hunterkiller/functions/script_component.hpp Co-authored-by: jonpas * Update for ArmA 2.08 * cleanup * Rework Observe / Control configs * Add to all 2035 tanks * Update script_component.hpp * Use eyeDirection on commander turrets * Update docs/wiki/framework/hunterkiller-framework.md Co-authored-by: Filip Maciejewski * Add to all 2035, support ture/false setVars * remove from apcs because mods don't know how to do inheritance Co-authored-by: jonpas Co-authored-by: Filip Maciejewski --- addons/hunterkiller/$PBOPREFIX$ | 1 + addons/hunterkiller/CfgEventHandlers.hpp | 15 ++++++ addons/hunterkiller/CfgVehicles.hpp | 24 +++++++++ addons/hunterkiller/README.md | 4 ++ addons/hunterkiller/XEH_PREP.hpp | 5 ++ addons/hunterkiller/XEH_postInit.sqf | 28 ++++++++++ addons/hunterkiller/XEH_preInit.sqf | 9 ++++ addons/hunterkiller/XEH_preStart.sqf | 3 ++ addons/hunterkiller/config.cpp | 17 ++++++ addons/hunterkiller/functions/fnc_keydown.sqf | 49 +++++++++++++++++ addons/hunterkiller/functions/fnc_slew.sqf | 32 ++++++++++++ .../functions/fnc_turretChangedEH.sqf | 52 +++++++++++++++++++ .../functions/script_component.hpp | 1 + addons/hunterkiller/script_component.hpp | 14 +++++ addons/hunterkiller/stringtable.xml | 20 +++++++ addons/main/script_mod.hpp | 2 +- docs/wiki/feature/hunterkiller.md | 26 ++++++++++ docs/wiki/framework/hunterkiller-framework.md | 50 ++++++++++++++++++ 18 files changed, 351 insertions(+), 1 deletion(-) create mode 100644 addons/hunterkiller/$PBOPREFIX$ create mode 100644 addons/hunterkiller/CfgEventHandlers.hpp create mode 100644 addons/hunterkiller/CfgVehicles.hpp create mode 100644 addons/hunterkiller/README.md create mode 100644 addons/hunterkiller/XEH_PREP.hpp create mode 100644 addons/hunterkiller/XEH_postInit.sqf create mode 100644 addons/hunterkiller/XEH_preInit.sqf create mode 100644 addons/hunterkiller/XEH_preStart.sqf create mode 100644 addons/hunterkiller/config.cpp create mode 100644 addons/hunterkiller/functions/fnc_keydown.sqf create mode 100644 addons/hunterkiller/functions/fnc_slew.sqf create mode 100644 addons/hunterkiller/functions/fnc_turretChangedEH.sqf create mode 100644 addons/hunterkiller/functions/script_component.hpp create mode 100644 addons/hunterkiller/script_component.hpp create mode 100644 addons/hunterkiller/stringtable.xml create mode 100644 docs/wiki/feature/hunterkiller.md create mode 100644 docs/wiki/framework/hunterkiller-framework.md diff --git a/addons/hunterkiller/$PBOPREFIX$ b/addons/hunterkiller/$PBOPREFIX$ new file mode 100644 index 0000000000..3474867891 --- /dev/null +++ b/addons/hunterkiller/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\hunterkiller \ No newline at end of file diff --git a/addons/hunterkiller/CfgEventHandlers.hpp b/addons/hunterkiller/CfgEventHandlers.hpp new file mode 100644 index 0000000000..2a3f71f852 --- /dev/null +++ b/addons/hunterkiller/CfgEventHandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/hunterkiller/CfgVehicles.hpp b/addons/hunterkiller/CfgVehicles.hpp new file mode 100644 index 0000000000..4ba64d8a95 --- /dev/null +++ b/addons/hunterkiller/CfgVehicles.hpp @@ -0,0 +1,24 @@ +class CfgVehicles { + class Tank_F; + class MBT_01_base_F: Tank_F { + ADDON = 1; // same as ADDON[] = {{{0}, 1}, {{0,0}, 3}}; + }; + class MBT_01_arty_base_F: MBT_01_base_F { + ADDON = 0; + }; + class MBT_01_mlrs_base_F: MBT_01_base_F { + ADDON = 0; + }; + class MBT_02_base_F: Tank_F { + ADDON = 1; + }; + class MBT_02_arty_base_F: MBT_02_base_F { + ADDON = 0; + }; + class MBT_03_base_F: Tank_F { + ADDON = 1; + }; + class MBT_04_base_F: Tank_F { + ADDON = 1; + }; +}; diff --git a/addons/hunterkiller/README.md b/addons/hunterkiller/README.md new file mode 100644 index 0000000000..293192db4e --- /dev/null +++ b/addons/hunterkiller/README.md @@ -0,0 +1,4 @@ +ace_hunterkiller +========== + +Allows a tank commander to re-aim the main turret or to aim their turret at the what the main turret is looking at diff --git a/addons/hunterkiller/XEH_PREP.hpp b/addons/hunterkiller/XEH_PREP.hpp new file mode 100644 index 0000000000..e0d7cd892e --- /dev/null +++ b/addons/hunterkiller/XEH_PREP.hpp @@ -0,0 +1,5 @@ +LOG("prep"); + +PREP(keydown); +PREP(slew); +PREP(turretChangedEH); diff --git a/addons/hunterkiller/XEH_postInit.sqf b/addons/hunterkiller/XEH_postInit.sqf new file mode 100644 index 0000000000..1560b6cc54 --- /dev/null +++ b/addons/hunterkiller/XEH_postInit.sqf @@ -0,0 +1,28 @@ +#include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +[QGVAR(slew), LINKFUNC(slew)] call CBA_fnc_addEventHandler; + +if (!hasInterface) exitWith {}; + +GVAR(mode) = 0; +GVAR(targetTurret) = []; + +["CBA_settingsInitialized", { + ["turret", LINKFUNC(turretChangedEH), true] call CBA_fnc_addPlayerEventHandler; +}] call CBA_fnc_addEventHandler; + + +["ACE3 Vehicles", QGVAR(observe), [format ["%1 - %2", LLSTRING(displayName), LLSTRING(observe)], LLSTRING(observe_description)], +{ + [false] call FUNC(keyDown) +}, { + false +}, [DIK_Q, [false, false, false]]] call CBA_fnc_addKeybind; + +["ACE3 Vehicles", QGVAR(override), [format ["%1 - %2", LLSTRING(displayName), LLSTRING(override)], LLSTRING(override_description)], +{ + [true] call FUNC(keyDown) +}, { + false +}, [DIK_E, [false, false, false]]] call CBA_fnc_addKeybind; diff --git a/addons/hunterkiller/XEH_preInit.sqf b/addons/hunterkiller/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/hunterkiller/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/hunterkiller/XEH_preStart.sqf b/addons/hunterkiller/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/hunterkiller/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/hunterkiller/config.cpp b/addons/hunterkiller/config.cpp new file mode 100644 index 0000000000..ff31bbede3 --- /dev/null +++ b/addons/hunterkiller/config.cpp @@ -0,0 +1,17 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common"}; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/hunterkiller/functions/fnc_keydown.sqf b/addons/hunterkiller/functions/fnc_keydown.sqf new file mode 100644 index 0000000000..ea6fa7933c --- /dev/null +++ b/addons/hunterkiller/functions/fnc_keydown.sqf @@ -0,0 +1,49 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Slew keybind pressed + * + * Arguments: + * 0: Override if true, Observe if false + * + * Return Value: + * None + * + * Example: + * [true] call ace_hunterkiller_fnc_keydown + * + * Public: No + */ + +if ((GVAR(mode) == MODE_NO_ACTIONS) || {!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith { + false +}; + +params ["_modeOverride"]; +TRACE_1("keydown",_modeOverride); +if ((_modeOverride) && {!(GVAR(mode) in [MODE_OVERRIDE, MODE_OBSERVE_AND_OVERRIDE])}) exitWith { false }; +if ((!_modeOverride) && {!(GVAR(mode) in [MODE_OBSERVE, MODE_OBSERVE_AND_OVERRIDE])}) exitWith { false }; + +private _vehicle = vehicle ACE_player; +private _playerTurret = _vehicle unitTurret ACE_player; + +private _sourceTurret = [GVAR(targetTurret), _playerTurret] select _modeOverride; +private _puppetTurret = [_playerTurret, GVAR(targetTurret)] select _modeOverride; +TRACE_3("",_modeOverride,_sourceTurret,_puppetTurret); + +private _eyePos = eyePos _vehicle; +private _lookDir = if ((getNumber (([_vehicle, _sourceTurret] call CBA_fnc_getTurret) >> "primaryObserver")) == 1) then { + TRACE_1("using commander",_sourceTurret); + // CBA_fnc_turretDir fails on "CUP_B_M1A2SEP_TUSK_II_NATO", but eyeDirection should be correct on commander turrets + eyeDirection _vehicle +} else { + ([1] + ([_vehicle, _sourceTurret] call CBA_fnc_turretDir)) call CBA_fnc_polar2vect +}; +private _lookPoint = _eyePos vectorAdd (_lookDir vectorMultiply 5000); + +TRACE_1("sending event",_lookDir); +[QGVAR(slew), [_vehicle, _puppetTurret, _lookPoint, _modeOverride], _vehicle, _puppetTurret] call CBA_fnc_turretEvent; + +playSound "ACE_Sound_Click"; + +true // return (key used) diff --git a/addons/hunterkiller/functions/fnc_slew.sqf b/addons/hunterkiller/functions/fnc_slew.sqf new file mode 100644 index 0000000000..97d66aa38f --- /dev/null +++ b/addons/hunterkiller/functions/fnc_slew.sqf @@ -0,0 +1,32 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Slews turret to target pos and shows visual feedback + * + * Arguments: + * 0: Vehicle + * 1: Turret (will be local) + * 2: Look PosASL + * 3: Override + * + * Return Value: + * None + * + * Example: + * [vehicle, [0], [0,0,0], true] call ace_hunterkiller_fnc_slew + * + * Public: No + */ + +params ["_vehicle", "_turret", "_posASL", "_isOverride"]; +TRACE_4("slew",_vehicle,_turret,_posASL,_isOverride); + +_vehicle lockCameraTo [_posASL, _turret, true]; + +if (hasInterface && {(_vehicle turretUnit _turret) isEqualTo ace_player}) then { + private _displayText = if (_isOverride) then { LLSTRING(override) } else { LLSTRING(observe) }; + QGVAR(text) cutText [format ["




[%1]", _displayText], "PLAIN", -1, false, true]; + [{ + QGVAR(text) cutText ["", "PLAIN"]; + }, [], 1] call CBA_fnc_waitAndExecute; +}; diff --git a/addons/hunterkiller/functions/fnc_turretChangedEH.sqf b/addons/hunterkiller/functions/fnc_turretChangedEH.sqf new file mode 100644 index 0000000000..88ca02fe98 --- /dev/null +++ b/addons/hunterkiller/functions/fnc_turretChangedEH.sqf @@ -0,0 +1,52 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Turret changed event handler. Determine if in a master turret + * + * Arguments: + * 0: Unit + * 1: Turret + * + * Return Value: + * None + * + * Example: + * [player, [0]] call ace_hunterkiller_fnc_turretChangedEH + * + * Public: No + */ + +params ["_player", "_playerTurret"]; +TRACE_2("turretChangedEH",_player,_playerTurret); + +GVAR(mode) = 0; +GVAR(targetTurret) = []; + +if (_playerTurret isEqualTo []) exitWith {}; +private _vehicle = vehicle _player; +private _config = configOf _vehicle; + +// setVar can be real array or true/false +private _hkArray = _vehicle getVariable [QUOTE(ADDON), nil]; +if (isNil "_hkArray") then { + _hkArray = if (isArray (_config >> QUOTE(ADDON))) then { + getArray (_config >> QUOTE(ADDON)) + } else { + ((getNumber (_config >> QUOTE(ADDON))) == 1) + }; +}; +if (_hkArray isEqualTo true) then { _hkArray = [[[0], 1], [[0,0], 3]]; }; +if (_hkArray isEqualTo false) then { _hkArray = []; }; + +TRACE_1("",_hkArray); +if ((count _hkArray) != 2) exitWith {}; + +{ + _x params ["_xTurret", "_xMode"]; + TRACE_2("x",_playerTurret,_xTurret); + if (_xTurret isEqualTo _playerTurret) exitWith { + TRACE_3("seat active",typeOf _vehicle,_xTurret,_xMode); + GVAR(mode) = _xMode; + GVAR(targetTurret) = _hkArray # ((_forEachIndex + 1) % 2) # 0; + }; +} forEach _hkArray; diff --git a/addons/hunterkiller/functions/script_component.hpp b/addons/hunterkiller/functions/script_component.hpp new file mode 100644 index 0000000000..5ad82702f2 --- /dev/null +++ b/addons/hunterkiller/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\hunterkiller\script_component.hpp" diff --git a/addons/hunterkiller/script_component.hpp b/addons/hunterkiller/script_component.hpp new file mode 100644 index 0000000000..75f4a0ead5 --- /dev/null +++ b/addons/hunterkiller/script_component.hpp @@ -0,0 +1,14 @@ +#define COMPONENT hunterkiller +#define COMPONENT_BEAUTIFIED Hunter Killer +#include "\z\ace\addons\main\script_mod.hpp" + +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS + +#include "\z\ace\addons\main\script_macros.hpp" + +#define MODE_NO_ACTIONS 0 +#define MODE_OBSERVE 1 +#define MODE_OVERRIDE 2 +#define MODE_OBSERVE_AND_OVERRIDE 3 diff --git a/addons/hunterkiller/stringtable.xml b/addons/hunterkiller/stringtable.xml new file mode 100644 index 0000000000..3152aaf8be --- /dev/null +++ b/addons/hunterkiller/stringtable.xml @@ -0,0 +1,20 @@ + + + + + Hunter Killer + + + Override + + + Force other turret to slew onto your viewpoint + + + Observe + + + Slew your turret onto other turret's viewpoint + + + diff --git a/addons/main/script_mod.hpp b/addons/main/script_mod.hpp index 8f1fcd1993..bc75d35819 100644 --- a/addons/main/script_mod.hpp +++ b/addons/main/script_mod.hpp @@ -10,7 +10,7 @@ #define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD // MINIMAL required version for the Mod. Components can specify others.. -#define REQUIRED_VERSION 2.06 +#define REQUIRED_VERSION 2.08 #define REQUIRED_CBA_VERSION {3,15,7} #ifdef COMPONENT_BEAUTIFIED diff --git a/docs/wiki/feature/hunterkiller.md b/docs/wiki/feature/hunterkiller.md new file mode 100644 index 0000000000..93f059d934 --- /dev/null +++ b/docs/wiki/feature/hunterkiller.md @@ -0,0 +1,26 @@ +--- +layout: wiki +title: Hunter Killer +component: hunterkiller +description: Allows commander turret to slew gunner to their target +group: feature +category: realism +parent: wiki +mod: ace +version: + major: 3 + minor: 15 + patch: 1 +--- + +## 1. Overview +Allows a gunner and commander to observe and remote control the other's weapon to their own target + +## 2. Usage + +### 2.1 Observe other turret +- Press Q + +### 2.2 Override other turret +- Place the crosshair on the enemy vehicle. +- Press E diff --git a/docs/wiki/framework/hunterkiller-framework.md b/docs/wiki/framework/hunterkiller-framework.md new file mode 100644 index 0000000000..09ec96e63a --- /dev/null +++ b/docs/wiki/framework/hunterkiller-framework.md @@ -0,0 +1,50 @@ +--- +layout: wiki +title: HunterKiller Framework +description: Explains configs of the hunter-killer addon +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 15 + patch: 1 +--- + +## 1. Array Info + +HunterKiller needs a 2 element array to know what seats to run on. +Each element is a tuple of a turret path and operating mode. +```cpp +// NO_ACTIONS = 0 +// OBSERVE = 1 +// OVERRIDE = 2 +// OBSERVE_AND_OVERRIDE = 3 +``` + + +## 2. Configs + +```cpp +class CfgVehicles { + class MyTankA { + ace_hunterkiller = 1; // enable with default settings + }; + class MyTankB { + ace_hunterkiller[] = {{{0}, 1}, {{0,0}, 3}}; // Default settings: (gunner can observe, commander can observe and override gunner) + }; + class MRAP_03_hmg_base_F { + ace_hunterkiller[] = {{{0}, 1}, {{1}, 2}}; // e.g. vehicle where commander is [1] instead of [0,0] + }; +}; +``` + +## 2. Variables + +```cpp +this setVariable ["ace_hunterkiller", true]; // enable for vic using default settings +this setVariable ["ace_hunterkiller", [[[0], 1], [[0,0], 3]]]; // enable using custom array +this setVariable ["ace_hunterkiller", false]; // disabled +this setVariable ["ace_hunterkiller", []]; // disabled +```