From 4fb0ea9a15b7f9e790132491c4b01122e9caf6d7 Mon Sep 17 00:00:00 2001 From: IndigoFox Date: Thu, 15 Feb 2024 12:32:01 -0800 Subject: [PATCH] rework PFH to client module, triageIcons and vehicleFlags point there --- framework/CfgFunctions.hpp | 9 +- .../client/functions/fn_addDraw3DPFH.sqf | 10 ++ .../client/functions/fn_addGetNearMenPFH.sqf | 17 +++ .../functions/fn_addMicroDAGRWaypoints.sqf | 29 ++++- framework/client/functions/fn_addPFHCode.sqf | 9 ++ .../client/functions/fn_clearPFHCode.sqf | 5 + framework/client/functions/fn_initClient.sqf | 5 + framework/common/functions/fn_log.sqf | 6 +- framework/init/functions/fn_initClient.sqf | 9 -- framework/init/functions/fn_initServer.sqf | 10 -- framework/mapcopy/functions/fn_initClient.sqf | 3 + .../functions/fn_addGetEntitiesPFH.sqf | 18 --- .../{fn_addDrawIconsPFH.sqf => fn_draw3D.sqf} | 40 +++---- .../triageIcons/functions/fn_initClient.sqf | 5 +- .../functions/fn_addFlagActions.sqf | 103 ++++++++++++++++++ .../vehicleFlags/functions/fn_draw3D.sqf | 40 +++++++ .../vehicleFlags/functions/fn_initClient.sqf | 97 +---------------- 17 files changed, 250 insertions(+), 165 deletions(-) create mode 100644 framework/client/functions/fn_addDraw3DPFH.sqf create mode 100644 framework/client/functions/fn_addGetNearMenPFH.sqf create mode 100644 framework/client/functions/fn_addPFHCode.sqf create mode 100644 framework/client/functions/fn_clearPFHCode.sqf delete mode 100644 framework/triageIcons/functions/fn_addGetEntitiesPFH.sqf rename framework/triageIcons/functions/{fn_addDrawIconsPFH.sqf => fn_draw3D.sqf} (64%) create mode 100644 framework/vehicleFlags/functions/fn_addFlagActions.sqf create mode 100644 framework/vehicleFlags/functions/fn_draw3D.sqf diff --git a/framework/CfgFunctions.hpp b/framework/CfgFunctions.hpp index 3753f23..3aeabc1 100644 --- a/framework/CfgFunctions.hpp +++ b/framework/CfgFunctions.hpp @@ -29,6 +29,10 @@ class DOUBLES(PREFIX,client) { class bindEventHandlers {}; class bindUnconsciousListener {}; class bindVehicleActions {}; + class addGetNearMenPFH {}; + class addDraw3DPFH {}; + class addPFHCode {}; + class clearPFHCode {}; }; }; @@ -156,8 +160,7 @@ class DOUBLES(PREFIX,triageIcons) { file = "framework\triageIcons\functions"; class addCBASettings {preInit=1;}; class initClient {}; - class addDrawIconsPFH {}; - class addGetEntitiesPFH {}; + class draw3D {}; class updateColors {}; }; }; @@ -166,6 +169,8 @@ class DOUBLES(PREFIX,vehicleFlags) { class functions { file = "framework\vehicleFlags\functions"; class initClient {}; + class addFlagActions {}; + class draw3D {}; class getActionsFlagCategories {}; class getVehicleFlagsCfg {}; class isClassExcluded {}; diff --git a/framework/client/functions/fn_addDraw3DPFH.sqf b/framework/client/functions/fn_addDraw3DPFH.sqf new file mode 100644 index 0000000..8b0626a --- /dev/null +++ b/framework/client/functions/fn_addDraw3DPFH.sqf @@ -0,0 +1,10 @@ +#include "..\script_component.hpp" + + +if (!isNil QGVAR(draw3DPFH)) then { + [GVAR(draw3DPFH)] call CBA_fnc_removePerFrameHandler; +}; +// add pfh that processes queued code +GVAR(draw3DPFH) = [{ + {call _x; true;} count (localNamespace getVariable [QGVAR(pfhCode), []]); +}, 0] call CBA_fnc_addPerFrameHandler; diff --git a/framework/client/functions/fn_addGetNearMenPFH.sqf b/framework/client/functions/fn_addGetNearMenPFH.sqf new file mode 100644 index 0000000..dbad6c5 --- /dev/null +++ b/framework/client/functions/fn_addGetNearMenPFH.sqf @@ -0,0 +1,17 @@ +#include "..\script_component.hpp" + +// subroutine to gather nearest 50 units every 5 seconds and store in GVAR(nearMen) +// cleanup +if (!isNil QGVAR(getNearMenPFH)) then { + [GVAR(getNearMenPFH)] call CBA_fnc_removePerFrameHandler; +}; +// add pfh +GVAR(getNearMenPFH) = [{ + localNamespace setVariable [ + QGVAR(nearMen), + (nearestObjects [player,["Man"],50,false]) select { + !isNull _x && + player isNotEqualTo _x + } + ]; +}, 1] call CBA_fnc_addPerFrameHandler; diff --git a/framework/client/functions/fn_addMicroDAGRWaypoints.sqf b/framework/client/functions/fn_addMicroDAGRWaypoints.sqf index f72e858..832bc54 100644 --- a/framework/client/functions/fn_addMicroDAGRWaypoints.sqf +++ b/framework/client/functions/fn_addMicroDAGRWaypoints.sqf @@ -23,11 +23,27 @@ if (!hasInterface) exitWith {}; ]; private _realPos = nil; // if pos was provided, process - if (count _pos > 0) then { - if (typeName _pos == "STRING") then { - _realPos = [_pos, true] call ACE_common_fnc_getMapPosFromGrid; - _realPos set [2, getTerrainHeightASL _realPos]; - } else {_realPos = _pos;}; + if (count _pos >= 2) then { + switch (typeName _pos) do { + case "ARRAY": { + // pos is provided as an array + _realPos = _pos select [0, 2]; + _realPos set [2, getTerrainHeightASL _realPos]; + }; + case "STRING": { + // pos is provided as a string + _realPos = [_pos, true] call ACE_common_fnc_getMapPosFromGrid; + _realPos set [2, getTerrainHeightASL _realPos]; + }; + default { + [ + LEVEL_WARNING, + QUOTE(COMPONENT), + format["Invalid position for custom microDAGR waypoint: %1", _wpName], + [["name", _wpName], ["pos", _pos], ["object", _object]]] call EFUNC(common,log); + continue; + }; + }; }; // if object was provided, process and override any pos if (count _object > 0) then { @@ -53,7 +69,8 @@ if (!hasInterface) exitWith {}; }; [_wpName, _realPos] call ace_microdagr_fnc_deviceAddWaypoint; - } forEach _customWaypoints; + true; + } count _customWaypoints; }] call CBA_fnc_waitUntilAndExecute; nil; \ No newline at end of file diff --git a/framework/client/functions/fn_addPFHCode.sqf b/framework/client/functions/fn_addPFHCode.sqf new file mode 100644 index 0000000..990dfec --- /dev/null +++ b/framework/client/functions/fn_addPFHCode.sqf @@ -0,0 +1,9 @@ +#include "..\script_component.hpp" + +params [["_code", {}, [{}]]]; + +private _pfhCode = localNamespace getVariable [QGVAR(pfhCode), []]; +_pfhCode pushBack _code; +localNamespace setVariable [QGVAR(pfhCode), _pfhCode]; + +count _pfhCode; \ No newline at end of file diff --git a/framework/client/functions/fn_clearPFHCode.sqf b/framework/client/functions/fn_clearPFHCode.sqf new file mode 100644 index 0000000..08129a5 --- /dev/null +++ b/framework/client/functions/fn_clearPFHCode.sqf @@ -0,0 +1,5 @@ +#include "..\script_component.hpp" + +localNamespace setVariable [QGVAR(pfhCode), []]; + +count []; \ No newline at end of file diff --git a/framework/client/functions/fn_initClient.sqf b/framework/client/functions/fn_initClient.sqf index e9ec764..357d6ec 100644 --- a/framework/client/functions/fn_initClient.sqf +++ b/framework/client/functions/fn_initClient.sqf @@ -8,6 +8,11 @@ call FUNC(addZenModules); call FUNC(bindEventHandlers); call FUNC(bindVehicleActions); +localNamespace setVariable [QGVAR(nearMen), []]; +call FUNC(addGetNearMenPFH); +localNamespace setVariable [QGVAR(pfhCode), []]; +call FUNC(addDraw3DPFH); + // add listener that tracks when the player goes unconscious and saves a variable with time call FUNC(bindUnconsciousListener); diff --git a/framework/common/functions/fn_log.sqf b/framework/common/functions/fn_log.sqf index 716c0df..11487e6 100644 --- a/framework/common/functions/fn_log.sqf +++ b/framework/common/functions/fn_log.sqf @@ -24,10 +24,10 @@ if (_logLevel < DEBUG_MODE) exitWith {}; private _hash = createHashMapFromArray _data; // Replace square brackets with round brackets to avoid parsing issues. -_message regexReplace ['(\[)', "("]; -_message regexReplace ['(\])', ")"]; +[_message, "]", ")"] call CBA_fnc_replace; +[_message, "[", "("] call CBA_fnc_replace; private _json = [_hash] call CBA_fnc_encodeJSON; -_log = format ["[%1] [%2] [%3] [%4] :: %5", QUOTE(PREFIX), _component, _fnc_scriptNameParent, _message, _json]; +private _log = format ["[%1] [%2] [%3] [%4] :: %5", QUOTE(PREFIX), _component, _fnc_scriptNameParent, _message, _json]; diag_log text _log; \ No newline at end of file diff --git a/framework/init/functions/fn_initClient.sqf b/framework/init/functions/fn_initClient.sqf index fc9f0d5..8f09921 100644 --- a/framework/init/functions/fn_initClient.sqf +++ b/framework/init/functions/fn_initClient.sqf @@ -2,13 +2,6 @@ if (!hasInterface) exitWith {}; -["milsim_logText", { - params [["_strArray", [""], [[]]]]; - { - diag_log text _x; - } forEach _strArray; -}] call CBA_fnc_addEventHandler; - // make sure the server has finished init waitUntil {!isNil QGVARMAIN(complete)}; @@ -18,8 +11,6 @@ waitUntil {!isNil QGVARMAIN(complete)}; call FUNC(addAARChatHandler); call FUNC(addRespawnChatHandler); call FUNC(setDefaults); -call FUNC(checkMissionSettings); - // Initialize a holder for managing local diary records // store records in format: diff --git a/framework/init/functions/fn_initServer.sqf b/framework/init/functions/fn_initServer.sqf index 84e2666..c40180e 100644 --- a/framework/init/functions/fn_initServer.sqf +++ b/framework/init/functions/fn_initServer.sqf @@ -9,16 +9,6 @@ publicVariable QGVARMAIN(baseObjects); // Initializes the Dynamic Groups framework and groups ["Initialize", [true]] call BIS_fnc_dynamicGroups; -if (isDedicated) then { - ["milsim_logText", { - params [["_strArray", [""], [[]]]]; - { - diag_log text _x; - } forEach _strArray; - }] call CBA_fnc_addEventHandler; -}; - - // initialize other modules call EFUNC(common,logMissionInfo); call EFUNC(fbcb2_assets,initServer); diff --git a/framework/mapcopy/functions/fn_initClient.sqf b/framework/mapcopy/functions/fn_initClient.sqf index 3287103..51c4304 100644 --- a/framework/mapcopy/functions/fn_initClient.sqf +++ b/framework/mapcopy/functions/fn_initClient.sqf @@ -10,6 +10,9 @@ private _mapCopyAction = "\a3\ui_f\data\igui\cfg\actions\talk_ca.paa", { params ["_target", "_player", "_params"]; + if (!isPlayer _target) exitWith { + format["%1 is not a player", name _target] call CBA_fnc_notify; + }; format["Copying map markers from %1", name _target] call CBA_fnc_notify; [QGVAR(mapCopyRequest), _this, _target] call CBA_fnc_targetEvent; }, diff --git a/framework/triageIcons/functions/fn_addGetEntitiesPFH.sqf b/framework/triageIcons/functions/fn_addGetEntitiesPFH.sqf deleted file mode 100644 index 781227e..0000000 --- a/framework/triageIcons/functions/fn_addGetEntitiesPFH.sqf +++ /dev/null @@ -1,18 +0,0 @@ -#include "..\script_component.hpp" - -// subroutine to gather nearest 50 units every 5 seconds and store in GVAR(drawTargets) -// cleanup -if (!isNil QGVAR(getEntitiesPFH)) then { - [GVAR(getEntitiesPFH)] call CBA_fnc_removePerFrameHandler; -}; -// add pfh -GVAR(getEntitiesPFH) = [{ - GVAR(drawTargets) = ( - (allUnits + allDeadMen) select { - _x isKindOf "CAManBase" && - player distance _x < 50 && - !isNull _x && - player isNotEqualTo _x - } - ); -}, 10] call CBA_fnc_addPerFrameHandler; diff --git a/framework/triageIcons/functions/fn_addDrawIconsPFH.sqf b/framework/triageIcons/functions/fn_draw3D.sqf similarity index 64% rename from framework/triageIcons/functions/fn_addDrawIconsPFH.sqf rename to framework/triageIcons/functions/fn_draw3D.sqf index 6478264..c4cb8d5 100644 --- a/framework/triageIcons/functions/fn_addDrawIconsPFH.sqf +++ b/framework/triageIcons/functions/fn_draw3D.sqf @@ -1,6 +1,6 @@ /* -milsim_fnc_addMedicalOverlayPFH +milsim_triageIcons_fnc_draw3D Author: IndigoFox @@ -14,30 +14,20 @@ Description: #include "..\script_component.hpp" +if (!hasInterface) exitWith {}; -// Per-frame handler to draw icons -// cleanup -if (!isNil QGVAR(drawIconsPfh)) then { - [GVAR(drawIconsPfh)] call CBA_fnc_removePerFrameHandler; -}; -// add pfh -GVAR(drawIconsPfh) = [{ + +// adds codeblock to common array to be processed per frame +private _code = { // if disabled, skip processing if (!GVAR(setting_enabled)) exitWith {false}; - // if no targets, skip processing - if (count GVAR(drawTargets) == 0) exitWith {false}; + // if the player doesn't have medical perms, skip processing if !([player] call ace_medical_treatment_fnc_isMedic) exitWith {false}; + { private _unit = _x; - // distance within X meters - if (player distance _unit > GVAR(setting_drawRange)) then {continue}; - // check unit not null, not conscious, and not in a vehicle - if ( - !(_unit getVariable ["ACE_isUnconscious", false]) || - !isNull (objectParent _unit) - ) then {continue}; - + // color based on triage level private _triageLevel = _unit getVariable ["ace_medical_triageLevel", 4]; if (_triageLevel == -1) then {continue}; @@ -57,6 +47,16 @@ GVAR(drawIconsPfh) = [{ true // outline // further params optional, omitted ]; - } forEach GVAR(drawTargets); -}, 0, []] call CBA_fnc_addPerFrameHandler; + true; + } count ( + (localNamespace getVariable [QEGVAR(client,nearMen), []]) select { + // is unconscious and is NOT in vehicle and is within draw range + (_x getVariable ["ACE_isUnconscious", false]) && + isNull (objectParent _x) && + player distance _x <= GVAR(setting_drawRange) + } + ); +}; +// add codeblock to common array +[_code] call EFUNC(client,addPFHCode); \ No newline at end of file diff --git a/framework/triageIcons/functions/fn_initClient.sqf b/framework/triageIcons/functions/fn_initClient.sqf index 7b22f9d..f14600a 100644 --- a/framework/triageIcons/functions/fn_initClient.sqf +++ b/framework/triageIcons/functions/fn_initClient.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" -// List of units to draw icons for -GVAR(drawTargets) = []; +if (!hasInterface) exitWith {}; + +call FUNC(draw3D); [ LEVEL_DEBUG, diff --git a/framework/vehicleFlags/functions/fn_addFlagActions.sqf b/framework/vehicleFlags/functions/fn_addFlagActions.sqf new file mode 100644 index 0000000..7b14721 --- /dev/null +++ b/framework/vehicleFlags/functions/fn_addFlagActions.sqf @@ -0,0 +1,103 @@ +#include "..\script_component.hpp" + +private _vehicleFlagsCfg = call FUNC(getVehicleFlagsCfg); + +if (!isClass _vehicleFlagsCfg) exitWith { + ["WARNING: Vehicle Flags: Vehicle Flags config not found. Vehicle Flags will not be available."] call BIS_fnc_error; +}; + +private _baseClassesToApplyActionsFor = + (_vehicleFlagsCfg >> "baseClassesToApplyActionsFor") call BIS_fnc_getCfgDataArray; +private _flagCategoryCfgs = (_vehicleFlagsCfg >> "FlagCategories") call BIS_fnc_returnChildren; + +{ // forEach _baseClassesToApplyActionsFor + private _parentClass = _x; + + //////////////////////////////////////////////////////////////////////// + // create the root action + //////////////////////////////////////////////////////////////////////// + private _rootActionID = QGVAR(SetVehicleFlagAction); + private _flagRootAction = [ + _rootActionID, // id + "Set Vehicle Flag", // displayed title + "\A3\ui_f\data\map\markers\flags\nato_ca.paa", // flag icon + { + params ["_target", "_player", "_params"]; + // set broadcasted variable of self to indicate we're looking at flags + _player setVariable [QGVAR(inFlagMenu), true, true]; + [{_this setVariable [QGVAR(inFlagMenu), false, true];}, _player, 3] call CBA_fnc_waitAndExecute; + true + }, // statement + { + params ["_target", "_player", "_params"]; + // _params params ["_parentActionID", "_flagCategories"]; + + // check if vehicle is excluded + private _excluded = [typeOf _target] call FUNC(isClassExcluded); + if (_excluded || !alive _target) exitWith {false}; + + true; + }, // condition + { + //////////////////////////////////////////////////////////////////////// + // create the flag category actions (with nested flag actions) + //////////////////////////////////////////////////////////////////////// + params ["_target", "_player", "_params"]; + _params params ["_rootActionID"]; + + private _vehicleFlagsCfg = call FUNC(getVehicleFlagsCfg); + if (isNull _vehicleFlagsCfg) exitWith {[]}; + private _flagCategoryCfgs = (_vehicleFlagsCfg >> "FlagCategories") call BIS_fnc_returnChildren; + + // return category child actions with individual flag actions nested as children + [_rootActionID, _flagCategoryCfgs] call FUNC(getActionsFlagCategories); + + }, // child code + [_rootActionID], // params + nil, // position + 4, // distance + [false, false, false, true, false], // other params - run on hover is true + nil // modifier function code + ] call ace_interact_menu_fnc_createAction; + + //////////////////////////////////////////////////////////////////////// + // add root action to add flags + //////////////////////////////////////////////////////////////////////// + [ + _parentClass, // parent classname + 0, // action 0 or self-action 1 + ["ACE_MainActions"], // parent + _flagRootAction, // action + true // apply to child classes + ] call ace_interact_menu_fnc_addActionToClass; + + //////////////////////////////////////////////////////////////////////// + // add action to remove flag under the root action + //////////////////////////////////////////////////////////////////////// + // create action + private _removeFlagAction = [ + _rootActionID + "_removeflag", // id + "Remove Flag", // displayed title + "\A3\ui_f\data\map\markers\flags\nato_ca.paa", // flag icon + { + params ["_target", "_player", "_params"]; + _target forceFlagTexture ""; + }, // statement + { + params ["_target", "_player", "_params"]; + alive _target && getForcedFlagTexture _target != ""; + }, // condition + nil // child code + ] call ace_interact_menu_fnc_createAction; + + // add the action to the vehicle + // in this class event handler, this#0 will be the vehicle + [ + _parentClass, // parent classname + 0, // action 0 or self-action 1 + ["ACE_MainActions", _rootActionID], // parent + _removeFlagAction, // action + true // apply to child classes + ] call ace_interact_menu_fnc_addActionToClass; + +} forEach _baseClassesToApplyActionsFor; \ No newline at end of file diff --git a/framework/vehicleFlags/functions/fn_draw3D.sqf b/framework/vehicleFlags/functions/fn_draw3D.sqf new file mode 100644 index 0000000..c654220 --- /dev/null +++ b/framework/vehicleFlags/functions/fn_draw3D.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" + +// we'll use this to display status if nearby players are in the flag menu + +// adds codeblock to common array to be processed per frame +private _code = { + { + private _unit = _x; + + // color based on triage level + private _color = [0.9, 0.9, 0.9, 1]; // default color + // draw position, slightly above the prone unit + private _drawPos = (visiblePosition _unit) vectorAdd [0, 0, 0.5]; + // draw icon + drawIcon3D [ + "", // icon texture + _color, // color + _drawPos, // position AGL + 1, // width + 1, // height + 0, // angle + "Setting vehicle flag...", // text + true // outline + // further params optional, omitted + ]; + true; + } count ( + (localNamespace getVariable [QEGVAR(client,nearMen), []]) select { + (_x getVariable [QGVAR(inFlagMenu), false]) && { + // distance within X meters + player distance _x <= 10 || + // check unit not in a vehicle + isNull (objectParent _x) + } + } + ); +}; + +// add codeblock to common array +[_code] call EFUNC(client,addPFHCode); \ No newline at end of file diff --git a/framework/vehicleFlags/functions/fn_initClient.sqf b/framework/vehicleFlags/functions/fn_initClient.sqf index b0d9537..f09a25c 100644 --- a/framework/vehicleFlags/functions/fn_initClient.sqf +++ b/framework/vehicleFlags/functions/fn_initClient.sqf @@ -2,101 +2,8 @@ if (!hasInterface) exitWith {}; -private _vehicleFlagsCfg = call FUNC(getVehicleFlagsCfg); - -if (!isClass _vehicleFlagsCfg) exitWith { - ["WARNING: Vehicle Flags: Vehicle Flags config not found. Vehicle Flags will not be available."] call BIS_fnc_error; -}; - -private _baseClassesToApplyActionsFor = - (_vehicleFlagsCfg >> "baseClassesToApplyActionsFor") call BIS_fnc_getCfgDataArray; -private _flagCategoryCfgs = (_vehicleFlagsCfg >> "FlagCategories") call BIS_fnc_returnChildren; - -{ // forEach _baseClassesToApplyActionsFor - private _parentClass = _x; - - //////////////////////////////////////////////////////////////////////// - // create the root action - //////////////////////////////////////////////////////////////////////// - private _rootActionID = QGVAR(SetVehicleFlagAction); - private _flagRootAction = [ - _rootActionID, // id - "Set Vehicle Flag", // displayed title - "\A3\ui_f\data\map\markers\flags\nato_ca.paa", // flag icon - {true}, // statement - { - params ["_target", "_player", "_params"]; - // _params params ["_parentActionID", "_flagCategories"]; - - // check if vehicle is excluded - private _excluded = [typeOf _target] call FUNC(isClassExcluded); - if (_excluded || !alive _target) exitWith {false}; - - true; - }, // condition - { - //////////////////////////////////////////////////////////////////////// - // create the flag category actions (with nested flag actions) - //////////////////////////////////////////////////////////////////////// - params ["_target", "_player", "_params"]; - _params params ["_rootActionID"]; - - private _vehicleFlagsCfg = call FUNC(getVehicleFlagsCfg); - if (isNull _vehicleFlagsCfg) exitWith {[]}; - private _flagCategoryCfgs = (_vehicleFlagsCfg >> "FlagCategories") call BIS_fnc_returnChildren; - - // return category child actions with individual flag actions nested as children - [_rootActionID, _flagCategoryCfgs] call FUNC(getActionsFlagCategories); - - }, // child code - [_rootActionID], // params - nil, // position - 4, // distance - [false, false, false, false, false], // other params - nil // modifier function code - ] call ace_interact_menu_fnc_createAction; - - //////////////////////////////////////////////////////////////////////// - // add root action to add flags - //////////////////////////////////////////////////////////////////////// - [ - _parentClass, // parent classname - 0, // action 0 or self-action 1 - ["ACE_MainActions"], // parent - _flagRootAction, // action - true // apply to child classes - ] call ace_interact_menu_fnc_addActionToClass; - - //////////////////////////////////////////////////////////////////////// - // add action to remove flag under the root action - //////////////////////////////////////////////////////////////////////// - // create action - private _removeFlagAction = [ - _rootActionID + "_removeflag", // id - "Remove Flag", // displayed title - "\A3\ui_f\data\map\markers\flags\nato_ca.paa", // flag icon - { - params ["_target", "_player", "_params"]; - _target forceFlagTexture ""; - }, // statement - { - params ["_target", "_player", "_params"]; - alive _target && getForcedFlagTexture _target != ""; - }, // condition - nil // child code - ] call ace_interact_menu_fnc_createAction; - - // add the action to the vehicle - // in this class event handler, this#0 will be the vehicle - [ - _parentClass, // parent classname - 0, // action 0 or self-action 1 - ["ACE_MainActions", _rootActionID], // parent - _removeFlagAction, // action - true // apply to child classes - ] call ace_interact_menu_fnc_addActionToClass; - -} forEach _baseClassesToApplyActionsFor; +call FUNC(addFlagActions); +call FUNC(draw3D); [ LEVEL_DEBUG,