Cleanup Interaction Menu

This commit is contained in:
PabstMirror 2016-01-07 22:43:37 -06:00
parent 71d4afcace
commit ed4cc42897
26 changed files with 326 additions and 339 deletions

View File

@ -79,8 +79,7 @@ GVAR(ParsedTextCached) = [];
//Debug to help end users identify mods that break CBA's XEH //Debug to help end users identify mods that break CBA's XEH
[{ [{
private ["_badClassnames"]; private _badClassnames = [];
_badClassnames = [];
{ {
//Only check Land objects (WeaponHolderSimulated show up in `vehicles` for some reason) //Only check Land objects (WeaponHolderSimulated show up in `vehicles` for some reason)
if ((_x isKindOf "Land") && {(isNil (format [QGVAR(Act_%1), typeOf _x])) || {isNil (format [QGVAR(SelfAct_%1), typeOf _x])}}) then { if ((_x isKindOf "Land") && {(isNil (format [QGVAR(Act_%1), typeOf _x])) || {isNil (format [QGVAR(SelfAct_%1), typeOf _x])}}) then {

View File

@ -30,9 +30,8 @@ if (_typeNum == 0) then {
[_objectType] call FUNC(compileMenuSelfAction); [_objectType] call FUNC(compileMenuSelfAction);
}; };
private ["_varName","_actionTrees", "_parentNode"]; private _varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType];
_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; private _actionTrees = missionNamespace getVariable [_varName, []];
_actionTrees = missionNamespace getVariable [_varName, []];
if((count _actionTrees) == 0) then { if((count _actionTrees) == 0) then {
missionNamespace setVariable [_varName, _actionTrees]; missionNamespace setVariable [_varName, _actionTrees];
}; };
@ -41,7 +40,7 @@ if (_parentPath isEqualTo ["ACE_MainActions"]) then {
[_objectType, _typeNum] call FUNC(addMainAction); [_objectType, _typeNum] call FUNC(addMainAction);
}; };
_parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode);
if (isNil {_parentNode}) exitWith { if (isNil {_parentNode}) exitWith {
ERROR("Failed to add action"); ERROR("Failed to add action");
ACE_LOGERROR_4("action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); ACE_LOGERROR_4("action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum);

View File

@ -23,10 +23,10 @@ if (!params [["_object", objNull, [objNull]], ["_typeNum", 0, [0]], ["_parentPat
ERROR("Bad Params"); ERROR("Bad Params");
}; };
private ["_varName","_actionList"]; private _varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum;
_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum; private _actionList = _object getVariable [_varName, []];
_actionList = _object getVariable [_varName, []];
if((count _actionList) == 0) then { if (_actionList isEqualTo []) then {
_object setVariable [_varName, _actionList]; _object setVariable [_varName, _actionList];
}; };

View File

@ -18,14 +18,12 @@
params ["_objectType", "_typeNum"]; params ["_objectType", "_typeNum"];
private["_actionTrees", "_mainAction", "_parentNode", "_varName"]; private _varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType];
private _actionTrees = missionNamespace getVariable [_varName, []];
_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType]; private _parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode);
_actionTrees = missionNamespace getVariable [_varName, []];
_parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode);
if (isNil {_parentNode}) then { if (isNil {_parentNode}) then {
TRACE_2("No Main Action on object", _objectType, _typeNum); TRACE_2("No Main Action on object", _objectType, _typeNum);
_mainAction = ["ACE_MainActions", localize ELSTRING(interaction,MainAction), "", {}, {true}] call FUNC(createAction); private _mainAction = ["ACE_MainActions", localize ELSTRING(interaction,MainAction), "", {}, {true}] call FUNC(createAction);
[_objectType, _typeNum, [], _mainAction] call EFUNC(interact_menu,addActionToClass); [_objectType, _typeNum, [], _mainAction] call EFUNC(interact_menu,addActionToClass);
}; };

View File

@ -6,6 +6,7 @@
* 0: Object <OBJECT> * 0: Object <OBJECT>
* 1: Original action tree <ARRAY> * 1: Original action tree <ARRAY>
* 2: Parent path <ARRAY> * 2: Parent path <ARRAY>
* 3: Distance to base point (will be 0 for self/zeus/in-vehicle) <NUMBER>
* *
* Return value: * Return value:
* Active children <ARRAY> * Active children <ARRAY>
@ -14,13 +15,11 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params ["_object", "_origAction", "_parentPath"]; params ["_object", "_origAction", "_parentPath", "_distanceToBasePoint"];
_origAction params ["_origActionData", "_origActionChildren"]; _origAction params ["_origActionData", "_origActionChildren"];
private ["_target","_player","_fullPath","_activeChildren","_dynamicChildren","_action","_actionData","_x"]; private _target = _object;
private _player = ACE_player;
_target = _object;
_player = ACE_player;
// Check if the function should be modified first // Check if the function should be modified first
if !((_origActionData select 10) isEqualTo {}) then { if !((_origActionData select 10) isEqualTo {}) then {
@ -29,54 +28,62 @@ if !((_origActionData select 10) isEqualTo {}) then {
[_target, ACE_player, _origActionData select 6, _origActionData] call (_origActionData select 10); [_target, ACE_player, _origActionData select 6, _origActionData] call (_origActionData select 10);
}; };
_origActionData params ["_actionName", "", "", "_statementCode", "_conditionCode", "_insertChildrenCode", "_customParams", "", "_distance"];
// Return nothing if the action itself is not active // Return nothing if the action itself is not active
if !([_target, ACE_player, _origActionData select 6] call (_origActionData select 4)) exitWith { if !([_target, ACE_player, _customParams] call _conditionCode) exitWith {
[] []
}; };
_fullPath = +_parentPath; // Return nothing if the action is to far (including checking sub actions) [DISABLED FOR NOW ref #2196]
_fullPath pushBack (_origActionData select 0); // if (_distanceToBasePoint > _distance) exitWith {
_activeChildren = []; // []
// };
private _fullPath = +_parentPath;
_fullPath pushBack _actionName;
private _activeChildren = [];
// If there's a statement to dynamically insert children then execute it // If there's a statement to dynamically insert children then execute it
if !({} isEqualTo (_origActionData select 5)) then { if !({} isEqualTo _insertChildrenCode) then {
_dynamicChildren = [_target, ACE_player, _origActionData select 6] call (_origActionData select 5); private _dynamicChildren = [_target, ACE_player, _customParams] call _insertChildrenCode;
// Collect dynamic children class actions // Collect dynamic children class actions
{ {
_action = [_x select 2, _x, _fullPath] call FUNC(collectActiveActionTree); private _action = [_x select 2, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree);
if ((count _action) > 0) then { if ((count _action) > 0) then {
_activeChildren pushBack _action; _activeChildren pushBack _action;
}; };
} forEach _dynamicChildren; nil
} count _dynamicChildren;
}; };
// Collect children class actions // Collect children class actions
{ {
_action = [_object, _x, _fullPath] call FUNC(collectActiveActionTree); private _action = [_object, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree);
if ((count _action) > 0) then { if ((count _action) > 0) then {
_activeChildren pushBack _action; _activeChildren pushBack _action;
}; };
} forEach _origActionChildren; nil
} count _origActionChildren;
// Collect children object actions // Collect children object actions
{ {
EXPLODE_2_PVT(_x,_actionData,_pPath); _x params ["_actionData", "_pPath"];
// Check if the action is children of the original action // Check if the action is children of the original action
if (count _pPath == count _fullPath && if (_pPath isEqualTo _fullPath) then {
{_pPath isEqualTo _fullPath}) then { private _action = [_object, [_actionData,[]], _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree);
_action = [_object, [_actionData,[]], _fullPath] call FUNC(collectActiveActionTree);
if ((count _action) > 0) then { if ((count _action) > 0) then {
_activeChildren pushBack _action; _activeChildren pushBack _action;
}; };
}; };
} forEach GVAR(objectActionList); nil
} count GVAR(objectActionList);
// If the original action has no statement, and no children, don't display it // If the original action has no statement, and no children, don't display it
if ((count _activeChildren) == 0 && ((_origActionData select 3) isEqualTo {})) exitWith { if ((_activeChildren isEqualTo []) && {_statementCode isEqualTo {}}) exitWith {
// @todo: Account for showDisabled? // @todo: Account for showDisabled?
[] []
}; };

View File

@ -14,34 +14,32 @@
params ["_target"]; params ["_target"];
private ["_objectType","_actionsVarName","_isMan"]; private _objectType = _target;
_objectType = _target; private _isMan = _target isKindOf "CAManBase";
_isMan = false;
if (_target isEqualType objNull) then { if (_target isEqualType objNull) then {
_objectType = typeOf _target; _objectType = typeOf _target;
_isMan = _target isKindOf "CAManBase";
}; };
_actionsVarName = format [QGVAR(Act_%1), _objectType]; private _actionsVarName = format [QGVAR(Act_%1), _objectType];
// Exit if the action menu is already compiled for this class // Exit if the action menu is already compiled for this class
if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {}; if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc"; private _recurseFnc = {
_recurseFnc = { params ["_actionsCfg", "_parentDistance"];
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_position", "_condition", "_showDisabled", "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction"]; private _actions = [];
params ["_actionsCfg"];
_actions = [];
{ {
_entryCfg = _x; private _entryCfg = _x;
if(isClass _entryCfg) then { if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName"); private _displayName = getText (_entryCfg >> "displayName");
_distance = getNumber (_entryCfg >> "distance"); private _distance = _parentDistance;
_icon = getText (_entryCfg >> "icon"); if (isNumber (_entryCfg >> "distance")) then {_distance = getNumber (_entryCfg >> "distance");};
_statement = compile (getText (_entryCfg >> "statement")); // if (_distance < _parentDistance) then {ACE_LOGWARNING_3("[%1] distance %2 less than parent %3", configName _entryCfg, _distance, _parentDistance);};
private _icon = getText (_entryCfg >> "icon");
private _statement = compile (getText (_entryCfg >> "statement"));
// If the position entry is present, compile it // If the position entry is present, compile it
_position = getText (_entryCfg >> "position"); private _position = getText (_entryCfg >> "position");
if (_position != "") then { if (_position != "") then {
_position = compile _position; _position = compile _position;
} else { } else {
@ -55,7 +53,7 @@ _recurseFnc = {
}; };
}; };
_condition = getText (_entryCfg >> "condition"); private _condition = getText (_entryCfg >> "condition");
if (_condition == "") then {_condition = "true"}; if (_condition == "") then {_condition = "true"};
// Add canInteract (including exceptions) and canInteractWith to condition // Add canInteract (including exceptions) and canInteractWith to condition
@ -63,13 +61,13 @@ _recurseFnc = {
_condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")];
}; };
_insertChildren = compile (getText (_entryCfg >> "insertChildren")); private _insertChildren = compile (getText (_entryCfg >> "insertChildren"));
_modifierFunction = compile (getText (_entryCfg >> "modifierFunction")); private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
_showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0; private _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
_enableInside = (getNumber (_entryCfg >> "enableInside")) > 0; private _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
_canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0; private _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
_runOnHover = false; private _runOnHover = false;
if (isText (_entryCfg >> "runOnHover")) then { if (isText (_entryCfg >> "runOnHover")) then {
_runOnHover = compile getText (_entryCfg >> "runOnHover"); _runOnHover = compile getText (_entryCfg >> "runOnHover");
} else { } else {
@ -77,9 +75,9 @@ _recurseFnc = {
}; };
_condition = compile _condition; _condition = compile _condition;
_children = [_entryCfg] call _recurseFnc; private _children = [_entryCfg, _distance] call _recurseFnc;
_entry = [ private _entry = [
[ [
configName _entryCfg, configName _entryCfg,
_displayName, _displayName,
@ -97,18 +95,20 @@ _recurseFnc = {
]; ];
_actions pushBack _entry; _actions pushBack _entry;
}; };
} forEach (configProperties [_actionsCfg, "isClass _x", true]); nil
} count (configProperties [_actionsCfg, "isClass _x", true]);
_actions _actions
}; };
private ["_actionsCfg","_actions"]; private _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions";
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions";
// If the classname inherits from CAManBase, just copy it's menu without recompiling a new one // If the classname inherits from CAManBase, just copy it's menu without recompiling a new one
_actions = if (_isMan) then { private _actions = if (_isMan && {_objectType != "CaManBase"}) then {
TRACE_1("Copying ACE_Actions from CAManBase",_objectType);
+ (missionNamespace getVariable QGVAR(Act_CAManBase)) + (missionNamespace getVariable QGVAR(Act_CAManBase))
} else { } else {
[_actionsCfg] call _recurseFnc TRACE_1("Building ACE_Actions",_objectType);
[_actionsCfg, 0] call _recurseFnc
}; };
missionNamespace setVariable [_actionsVarName, _actions]; missionNamespace setVariable [_actionsVarName, _actions];
@ -125,7 +125,7 @@ missionNamespace setVariable [_actionsVarName, _actions];
[], [],
{[0,0,0]}, {[0,0,0]},
1, 1,
[false,false,false] [false,false,false,false,false]
], ],
[children actions] [children actions]
] ]

View File

@ -14,46 +14,43 @@
params ["_target"]; params ["_target"];
private ["_objectType","_actionsVarName","_isMan"]; private _objectType = _target;
_objectType = _target; private _isMan = _target isKindOf "CAManBase";
_isMan = false;
if (_target isEqualType objNull) then { if (_target isEqualType objNull) then {
_objectType = typeOf _target; _objectType = typeOf _target;
_isMan = _target isKindOf "CAManBase";
}; };
_actionsVarName = format [QGVAR(SelfAct_%1), _objectType]; private _actionsVarName = format [QGVAR(SelfAct_%1), _objectType];
// Exit if the action menu is already compiled for this class // Exit if the action menu is already compiled for this class
if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {}; if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc";
_recurseFnc = { private _recurseFnc = {
private ["_actions", "_displayName", "_icon", "_statement", "_condition", "_showDisabled",
"_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction"];
params ["_actionsCfg"]; params ["_actionsCfg"];
_actions = [];
private _actions = [];
{ {
_entryCfg = _x; private _entryCfg = _x;
if(isClass _entryCfg) then { if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName"); private _displayName = getText (_entryCfg >> "displayName");
_icon = getText (_entryCfg >> "icon"); private _icon = getText (_entryCfg >> "icon");
_statement = compile (getText (_entryCfg >> "statement")); private _statement = compile (getText (_entryCfg >> "statement"));
_condition = getText (_entryCfg >> "condition"); private _condition = getText (_entryCfg >> "condition");
if (_condition == "") then {_condition = "true"}; if (_condition == "") then {_condition = "true"};
// Add canInteract (including exceptions) and canInteractWith to condition // Add canInteract (including exceptions) and canInteractWith to condition
_condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")]; _condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")];
_insertChildren = compile (getText (_entryCfg >> "insertChildren")); private _insertChildren = compile (getText (_entryCfg >> "insertChildren"));
_modifierFunction = compile (getText (_entryCfg >> "modifierFunction")); private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
_showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0; private _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
_enableInside = (getNumber (_entryCfg >> "enableInside")) > 0; private _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
_canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0; private _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
_runOnHover = true; private _runOnHover = true;
if (isText (_entryCfg >> "runOnHover")) then { if (isText (_entryCfg >> "runOnHover")) then {
_runOnHover = compile getText (_entryCfg >> "runOnHover"); _runOnHover = compile getText (_entryCfg >> "runOnHover");
} else { } else {
@ -61,9 +58,9 @@ _recurseFnc = {
}; };
_condition = compile _condition; _condition = compile _condition;
_children = [_entryCfg] call _recurseFnc; private _children = [_entryCfg] call _recurseFnc;
_entry = [ private _entry = [
[ [
configName _entryCfg, configName _entryCfg,
_displayName, _displayName,
@ -81,16 +78,15 @@ _recurseFnc = {
]; ];
_actions pushBack _entry; _actions pushBack _entry;
}; };
} forEach (configProperties [_actionsCfg, "isClass _x", true]); nil
} count (configProperties [_actionsCfg, "isClass _x", true]);
_actions _actions
}; };
private ["_actionsCfg","_actions"]; private _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
private ["_baseDisplayName", "_baseIcon"]; private _baseDisplayName = "";
_baseDisplayName = ""; private _baseIcon = "";
_baseIcon = "";
if (_objectType isKindOf "CAManBase") then { if (_objectType isKindOf "CAManBase") then {
_baseDisplayName = localize LSTRING(SelfActionsRoot); _baseDisplayName = localize LSTRING(SelfActionsRoot);
_baseIcon = "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa"; _baseIcon = "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa";
@ -108,9 +104,11 @@ if (_objectType isKindOf "CAManBase") then {
}; };
// If the classname inherits from CAManBase, just copy it's menu without recompiling a new one // If the classname inherits from CAManBase, just copy it's menu without recompiling a new one
_actions = if (_isMan) then { private _actions = if (_isMan && {_objectType != "CaManBase"}) then {
TRACE_1("badbeef Copying ACE_SelfActions from CAManBase",_objectType);
+ (missionNamespace getVariable QGVAR(SelfAct_CAManBase)) + (missionNamespace getVariable QGVAR(SelfAct_CAManBase))
} else { } else {
TRACE_1("Building ACE_SelfActions",_objectType);
// Create a master action to base on self action // Create a master action to base on self action
[ [
[ [
@ -127,7 +125,7 @@ _actions = if (_isMan) then {
{}, {},
"Spine3", "Spine3",
10, 10,
[false,true,false] [false,true,false,false,false]
], ],
[_actionsCfg] call _recurseFnc [_actionsCfg] call _recurseFnc
] ]

View File

@ -15,41 +15,38 @@
// Exit if the action menu is already compiled for zeus // Exit if the action menu is already compiled for zeus
if !(isNil {missionNamespace getVariable [QGVAR(ZeusActions), nil]}) exitWith {}; if !(isNil {missionNamespace getVariable [QGVAR(ZeusActions), nil]}) exitWith {};
private "_recurseFnc"; private _recurseFnc = {
_recurseFnc = {
private ["_actions", "_displayName", "_icon", "_statement", "_condition", "_showDisabled",
"_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction"];
params ["_actionsCfg"]; params ["_actionsCfg"];
_actions = []; private _actions = [];
{ {
_entryCfg = _x; private _entryCfg = _x;
if(isClass _entryCfg) then { if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName"); private _displayName = getText (_entryCfg >> "displayName");
_icon = getText (_entryCfg >> "icon"); private _icon = getText (_entryCfg >> "icon");
_statement = compile (getText (_entryCfg >> "statement")); private _statement = compile (getText (_entryCfg >> "statement"));
_condition = getText (_entryCfg >> "condition"); private _condition = getText (_entryCfg >> "condition");
if (_condition == "") then {_condition = "true"}; if (_condition == "") then {_condition = "true"};
_insertChildren = compile (getText (_entryCfg >> "insertChildren")); private _insertChildren = compile (getText (_entryCfg >> "insertChildren"));
_modifierFunction = compile (getText (_entryCfg >> "modifierFunction")); private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
_showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0; private _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
_enableInside = (getNumber (_entryCfg >> "enableInside")) > 0; private _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
_canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0; private _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
_runOnHover = true; private _runOnHover = true;
if (isText (_entryCfg >> "runOnHover")) then { if (isText (_entryCfg >> "runOnHover")) then {
_runOnHover = compile getText (_entryCfg >> "runOnHover"); _runOnHover = compile getText (_entryCfg >> "runOnHover");
} else { } else {
_runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0; _runOnHover = (getNumber (_entryCfg >> "runOnHover")) > 0;
}; };
_condition = compile _condition; private _condition = compile _condition;
_children = [_entryCfg] call _recurseFnc; private _children = [_entryCfg] call _recurseFnc;
_entry = [ private _entry = [
[ [
configName _entryCfg, configName _entryCfg,
_displayName, _displayName,
@ -60,7 +57,7 @@ _recurseFnc = {
{}, {},
[0,0,0], [0,0,0],
10, //distace 10, //distace
[_showDisabled,_enableInside,_canCollapse,_runOnHover], [_showDisabled,_enableInside,_canCollapse,_runOnHover,false],
_modifierFunction _modifierFunction
], ],
_children _children
@ -71,8 +68,7 @@ _recurseFnc = {
_actions _actions
}; };
private ["_actionsCfg"]; private _actionsCfg = configFile >> "ACE_ZeusActions";
_actionsCfg = configFile >> "ACE_ZeusActions";
// Create a master action to base zeus actions on // Create a master action to base zeus actions on
GVAR(ZeusActions) = [ GVAR(ZeusActions) = [
@ -87,7 +83,7 @@ GVAR(ZeusActions) = [
{}, {},
{[0,0,0]}, {[0,0,0]},
10, 10,
[false,true,false] [false,true,false,false,false]
], ],
[_actionsCfg] call _recurseFnc [_actionsCfg] call _recurseFnc
] ]

View File

@ -13,7 +13,7 @@
* 6: Action parameters <ANY> (Optional) * 6: Action parameters <ANY> (Optional)
* 7: Position (Position array, Position code or Selection Name) <ARRAY>, <CODE> or <STRING> (Optional) * 7: Position (Position array, Position code or Selection Name) <ARRAY>, <CODE> or <STRING> (Optional)
* 8: Distance <NUMBER> (Optional) * 8: Distance <NUMBER> (Optional)
* 9: Other parameters <ARRAY> (Optional) * 9: Other parameters [showDisabled,enableInside,canCollapse,runOnHover,doNotCheckLOS] <ARRAY> (Optional)
* 10: Modifier function <CODE> (Optional) * 10: Modifier function <CODE> (Optional)
* *
* Return value: * Return value:
@ -26,6 +26,8 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
// IGNORE_PRIVATE_WARNING(_actionName,_displayName,_icon,_statement,_condition,_insertChildren,_customParams,_position,_distance,_params,_modifierFunction);
params [ params [
"_actionName", "_actionName",
"_displayName", "_displayName",
@ -41,16 +43,16 @@ params [
]; ];
_position = if (_position isEqualType "") then { _position = if (_position isEqualType "") then {
// If the action is set to a selection, create the suitable code // If the action is set to a selection, create the suitable code - IGNORE_PRIVATE_WARNING(_target);
compile format ["_target selectionPosition '%1'", _position]; compile format ["_target selectionPosition '%1'", _position];
} else {
if (_position isEqualType []) then {
// If the action is set to a array position, create the suitable code
compile format ["%1", _position];
} else { } else {
if (_position isEqualType []) then { _position;
// If the action is set to a array position, create the suitable code
compile format ["%1", _position];
} else {
_position;
};
}; };
};
[ [
_actionName, _actionName,
@ -58,7 +60,6 @@ _position = if (_position isEqualType "") then {
_icon, _icon,
_statement, _statement,
_condition, _condition,
_insertChildren, _insertChildren,
_customParams, _customParams,
_position, _position,

View File

@ -1,11 +1,24 @@
// by commy2 /*
* Author: commy2
* Sets the controls structured text if it isn't already set.
*
* Argument:
* 0: Structured Text Ctrl <CONTROL>
* 1: Index <NUMBER>
* 2: Text <STRING>
*
* Return value:
* None
*
* Public: No
*/
#include "script_component.hpp" #include "script_component.hpp"
params ["_ctrl", "_index", "_text"]; params ["_ctrl", "_index", "_text"];
//systemChat str (_text != ARR_SELECT(GVAR(ParsedTextCached),_index,"-1")); //systemChat str (_text != ARR_SELECT(GVAR(ParsedTextCached),_index,"-1"));
if (_text != ARR_SELECT(GVAR(ParsedTextCached),_index,"-1")) then { if (_text != (GVAR(ParsedTextCached) param [_index,"-1"])) then {
GVAR(ParsedTextCached) set [_index, _text]; GVAR(ParsedTextCached) set [_index, _text];
_ctrl ctrlSetStructuredText parseText _text; _ctrl ctrlSetStructuredText parseText _text;
}; };

View File

@ -11,7 +11,7 @@
* Action node <ARRAY> or <NIL> if not found * Action node <ARRAY> or <NIL> if not found
* *
* Example: * Example:
* [_actionTree, ["ACE_TapShoulderRight","VulcanPinchAction"]] call ace_interact_menu_fnc_findActionNode; * [actionTree, ["ACE_TapShoulderRight","VulcanPinchAction"]] call ace_interact_menu_fnc_findActionNode;
* *
* Public: No * Public: No
*/ */
@ -19,18 +19,16 @@
params ["_actionTreeList", "_parentPath"]; params ["_actionTreeList", "_parentPath"];
private ["_parentNode", "_foundParentNode", "_fnc_findFolder", "_actionTree"];
// Hack to make this work on the root node too // Hack to make this work on the root node too
if (count _parentPath == 0) exitWith { if (_parentPath isEqualTo []) exitWith {
[[],_actionTreeList] [[],_actionTreeList]
}; };
// Search the class action trees and find where to insert the entry // Search the class action trees and find where to insert the entry
_parentNode = [[],_actionTreeList]; private _parentNode = [[],_actionTreeList];
_foundParentNode = false; private _foundParentNode = false;
_fnc_findFolder = { private _fnc_findFolder = {
params ["_parentPath", "_level", "_actionNode"]; params ["_parentPath", "_level", "_actionNode"];
{ {

View File

@ -14,8 +14,7 @@
params ["_newUnit", "_oldUnit"]; params ["_newUnit", "_oldUnit"];
// add to new unit // add to new unit
private "_ehid"; private _ehid = [_newUnit, "DefaultAction", {GVAR(openedMenuType) >= 0}, {
_ehid = [_newUnit, "DefaultAction", {GVAR(openedMenuType) >= 0}, {
if (!GVAR(actionOnKeyRelease) && GVAR(actionSelected)) then { if (!GVAR(actionOnKeyRelease) && GVAR(actionSelected)) then {
[GVAR(openedMenuType),true] call FUNC(keyUp); [GVAR(openedMenuType),true] call FUNC(keyUp);
}; };

View File

@ -9,18 +9,20 @@
* Return value: * Return value:
* Bool * Bool
* *
* Example:
* [[["ACE_SelfActions", player],["ace_Gestures", player]], [["ACE_SelfActions", player]]] call ace_interact_menu_fnc_isSubPath
*
* Public: No * Public: No
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params ["_longPath", "_shortPath"]; params ["_longPath", "_shortPath"];
private ["_isSubPath","_i"]; private _isSubPath = true;
_isSubPath = true;
if (count _shortPath > count _longPath) exitWith {false}; if (count _shortPath > count _longPath) exitWith {false};
for [{_i = 0},{_i < count _shortPath},{_i = _i + 1}] do { for [{private _i = 0},{_i < count _shortPath},{_i = _i + 1}] do {
if !((_longPath select _i) isEqualTo (_shortPath select _i)) exitWith { if !((_longPath select _i) isEqualTo (_shortPath select _i)) exitWith {
_isSubPath = false; _isSubPath = false;
}; };

View File

@ -65,7 +65,7 @@ if (GVAR(useCursorMenu)) then {
// uiNamespace getVariable QGVAR(cursorMenuOpened); // uiNamespace getVariable QGVAR(cursorMenuOpened);
GVAR(cursorPos) = [0.5,0.5,0]; GVAR(cursorPos) = [0.5,0.5,0];
_ctrl = (findDisplay 91919) ctrlCreate ["RscStructuredText", 9922]; private _ctrl = (findDisplay 91919) ctrlCreate ["RscStructuredText", 9922];
_ctrl ctrlSetPosition [safeZoneX, safeZoneY, safeZoneW, safeZoneH]; _ctrl ctrlSetPosition [safeZoneX, safeZoneY, safeZoneW, safeZoneH];
_ctrl ctrlCommit 0; _ctrl ctrlCommit 0;
@ -75,8 +75,7 @@ if (GVAR(useCursorMenu)) then {
setMousePosition [0.5, 0.5]; setMousePosition [0.5, 0.5];
}; };
GVAR(selfMenuOffset) = ((positionCameraToWorld [0, 0, 2]) call EFUNC(common,positionToASL)) vectorDiff GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff (AGLtoASL (positionCameraToWorld [0, 0, 0]));
((positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL));
if (GVAR(menuAnimationSpeed) > 0) then { if (GVAR(menuAnimationSpeed) > 0) then {
//Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice)

View File

@ -24,9 +24,8 @@ if (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]) then {
if(GVAR(actionSelected)) then { if(GVAR(actionSelected)) then {
this = GVAR(selectedTarget); this = GVAR(selectedTarget);
private ["_player","_target","_actionData"]; private _player = ACE_Player;
_player = ACE_Player; private _target = GVAR(selectedTarget);
_target = GVAR(selectedTarget);
// Clear the conditions caches // Clear the conditions caches
["clearConditionCaches", []] call EFUNC(common,localEvent); ["clearConditionCaches", []] call EFUNC(common,localEvent);
@ -35,7 +34,7 @@ if(GVAR(actionSelected)) then {
if (!(GVAR(actionOnKeyRelease)) && !_calledByClicking) exitWith {}; if (!(GVAR(actionOnKeyRelease)) && !_calledByClicking) exitWith {};
// Check the action conditions // Check the action conditions
_actionData = GVAR(selectedAction) select 0; private _actionData = GVAR(selectedAction) select 0;
if ([_target, _player, _actionData select 6] call (_actionData select 4)) then { if ([_target, _player, _actionData select 6] call (_actionData select 4)) then {
// Call the statement // Call the statement
[_target, _player, _actionData select 6] call (_actionData select 3); [_target, _player, _actionData select 6] call (_actionData select 3);

View File

@ -8,8 +8,12 @@
* Return value: * Return value:
* None * None
* *
* Example:
* [] call ace_interact_menu_fnc_render
*
* Public: No * Public: No
*/ */
// #define ENABLE_PERFORMANCE_COUNTERS
#include "script_component.hpp" #include "script_component.hpp"
BEGIN_COUNTER(fnc_render); BEGIN_COUNTER(fnc_render);
@ -42,7 +46,7 @@ if (GVAR(openedMenuType) >= 0) then {
}; };
} forEach GVAR(currentOptions); } forEach GVAR(currentOptions);
if(_closestSelection == -1) exitWith {}; if (_closestSelection == -1) exitWith {END_COUNTER(fnc_renderMenuOpen);};
private _closest = GVAR(currentOptions) select _closestSelection; private _closest = GVAR(currentOptions) select _closestSelection;
_closest params ["_action", "_sPos", "_hoverPath"]; _closest params ["_action", "_sPos", "_hoverPath"];

View File

@ -14,56 +14,57 @@
GVAR(currentOptions) = []; GVAR(currentOptions) = [];
private ["_player","_numInteractObjects","_numInteractions","_actionsVarName","_classActions","_target","_player","_action","_cameraPos","_cameraDir", "_lambda", "_nearestObjects", "_pos", "_virtualPoint", "_wavesAtOrigin", "_wavesAtVirtualPoint"]; private _player = ACE_player;
_player = ACE_player;
_cameraPos = (positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL); private _cameraPosASL = AGLtoASL (positionCameraToWorld [0, 0, 0]);
_cameraDir = ((positionCameraToWorld [0, 0, 1]) call EFUNC(common,positionToASL)) vectorDiff _cameraPos; private _cameraDir = (AGLtoASL (positionCameraToWorld [0, 0, 1])) vectorDiff _cameraPosASL;
_fnc_renderNearbyActions = { private _fnc_renderNearbyActions = {
// Render all nearby interaction menus // Render all nearby interaction menus
#define MAXINTERACTOBJECTS 3 #define MAXINTERACTOBJECTS 3
GVAR(foundActions) = []; GVAR(foundActions) = [];
GVAR(lastTimeSearchedActions) = ACE_diagTime; GVAR(lastTimeSearchedActions) = ACE_diagTime;
_numInteractObjects = 0; private _numInteractObjects = 0;
_nearestObjects = nearestObjects [ACE_player, ["All"], 13]; private _nearestObjects = nearestObjects [ACE_player, ["All"], 13];
{ {
_target = _x; private _target = _x;
// Quick oclussion test. Skip objects more than 1 m behind the camera plane // Quick oclussion test. Skip objects more than 1 m behind the camera plane
_lambda = ((getPosASL _x) vectorDiff _cameraPos) vectorDotProduct _cameraDir; private _lambda = ((getPosASL _x) vectorDiff _cameraPosASL) vectorDotProduct _cameraDir;
if ((_lambda > -1) && {!isObjectHidden _target}) then { if ((_lambda > -1) && {!isObjectHidden _target}) then {
_numInteractions = 0; private _numInteractions = 0;
// Prevent interacting with yourself or your own vehicle // Prevent interacting with yourself or your own vehicle
if (_target != ACE_player && {_target != vehicle ACE_player}) then { if (_target != ACE_player && {_target != vehicle ACE_player}) then {
// Iterate through object actions, find base level actions and render them if appropiate // Iterate through object actions, find base level actions and render them if appropiate
_actionsVarName = format [QGVAR(Act_%1), typeOf _target];
GVAR(objectActionList) = _target getVariable [QGVAR(actions), []]; GVAR(objectActionList) = _target getVariable [QGVAR(actions), []];
{ {
// Only render them directly if they are base level actions // Only render them directly if they are base level actions
if (count (_x select 1) == 0) then { if ((_x select 1) isEqualTo []) then {
// Try to render the menu // Try to render the menu
_action = _x; private _action = _x;
if ([_target, _action] call FUNC(renderBaseMenu)) then { if ([_target, _action] call FUNC(renderBaseMenu)) then {
_numInteractions = _numInteractions + 1; _numInteractions = _numInteractions + 1;
GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)]; GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)];
}; };
}; };
} forEach GVAR(objectActionList); nil
} count GVAR(objectActionList);
// Iterate through base level class actions and render them if appropiate // Iterate through base level class actions and render them if appropiate
_classActions = missionNamespace getVariable [_actionsVarName, []]; private _actionsVarName = format [QGVAR(Act_%1), typeOf _target];
private _classActions = missionNamespace getVariable [_actionsVarName, []];
{ {
_action = _x; private _action = _x;
// Try to render the menu // Try to render the menu
if ([_target, _action] call FUNC(renderBaseMenu)) then { if ([_target, _action] call FUNC(renderBaseMenu)) then {
_numInteractions = _numInteractions + 1; _numInteractions = _numInteractions + 1;
GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)]; GVAR(foundActions) pushBack [_target, _action, GVAR(objectActionList)];
}; };
} forEach _classActions; nil
} count _classActions;
// Limit the amount of objects the player can interact with // Limit the amount of objects the player can interact with
if (_numInteractions > 0) then { if (_numInteractions > 0) then {
@ -73,44 +74,33 @@ _fnc_renderNearbyActions = {
}; };
if (_numInteractObjects >= MAXINTERACTOBJECTS) exitWith {}; if (_numInteractObjects >= MAXINTERACTOBJECTS) exitWith {};
} forEach _nearestObjects; nil
} count _nearestObjects;
}; };
_fnc_renderLastFrameActions = { private _fnc_renderLastFrameActions = {
{ {
_x params ["_target", "_action", "_objectActionList"]; _x params ["_target", "_action", "_objectActionList"];
GVAR(objectActionList) = _objectActionList; GVAR(objectActionList) = _objectActionList;
[_target, _action] call FUNC(renderBaseMenu); [_target, _action] call FUNC(renderBaseMenu);
} forEach GVAR(foundActions); nil
} count GVAR(foundActions);
}; };
_fnc_renderSelfActions = { private _fnc_renderSelfActions = {
_target = _this; private _target = _this;
// Iterate through object actions, find base level actions and render them if appropiate // Set object actions for collectActiveActionTree
_actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target];
GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []]; GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []];
/*
{
_action = _x;
// Only render them directly if they are base level actions
if (count (_action select 7) == 1) then {
[_target, _action, 0, [180, 360]] call FUNC(renderMenu);
};
} forEach GVAR(objectActionList);
*/
// Iterate through base level class actions and render them if appropiate // Iterate through base level class actions and render them if appropiate
_actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target]; private _actionsVarName = format [QGVAR(SelfAct_%1), typeOf _target];
_classActions = missionNamespace getVariable [_actionsVarName, []]; private _classActions = missionNamespace getVariable [_actionsVarName, []];
_pos = if !(GVAR(useCursorMenu)) then { private _pos = if !(GVAR(useCursorMenu)) then {
_virtualPoint = (((positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL)) vectorAdd GVAR(selfMenuOffset)) call EFUNC(common,ASLToPosition); //Convert to ASL, add offset and then convert back to AGL (handles waves when over water)
_wavesAtOrigin = [(positionCameraToWorld [0, 0, 0])] call EFUNC(common,waveHeightAt); ASLtoAGL ((AGLtoASL (positionCameraToWorld [0, 0, 0])) vectorAdd GVAR(selfMenuOffset));
_wavesAtVirtualPoint = [_virtualPoint] call EFUNC(common,waveHeightAt);
_virtualPoint set [2, ((_virtualPoint select 2) - _wavesAtOrigin + _wavesAtVirtualPoint)];
_virtualPoint
} else { } else {
[0.5, 0.5] [0.5, 0.5]
}; };
@ -118,14 +108,16 @@ _fnc_renderSelfActions = {
{ {
_action = _x; _action = _x;
[_target, _action, _pos] call FUNC(renderBaseMenu); [_target, _action, _pos] call FUNC(renderBaseMenu);
} forEach _classActions; nil
} count _classActions;
}; };
_fnc_renderZeusActions = { private _fnc_renderZeusActions = {
{ {
_action = _x; private _action = _x;
[_this, _action, [0.5, 0.5]] call FUNC(renderBaseMenu); [_this, _action, [0.5, 0.5]] call FUNC(renderBaseMenu);
} forEach GVAR(ZeusActions); nil
} count GVAR(ZeusActions);
}; };
@ -160,11 +152,10 @@ if (count GVAR(collectedActionPoints) > 1) then {
// Order action points according to z // Order action points according to z
GVAR(collectedActionPoints) sort true; GVAR(collectedActionPoints) sort true;
private ["_i","_j","_delta"]; for [{private _i = count GVAR(collectedActionPoints) - 1}, {_i > 0}, {_i = _i - 1}] do {
for [{_i = count GVAR(collectedActionPoints) - 1}, {_i > 0}, {_i = _i - 1}] do { for [{private _j = _i - 1}, {_j >= 0}, {_j = _j - 1}] do {
for [{_j = _i - 1}, {_j >= 0}, {_j = _j - 1}] do {
// Check if action point _i is ocluded by _j // Check if action point _i is ocluded by _j
_delta = vectorNormalized ((GVAR(collectedActionPoints) select _i select 1) vectorDiff (GVAR(collectedActionPoints) select _j select 1)); private _delta = vectorNormalized ((GVAR(collectedActionPoints) select _i select 1) vectorDiff (GVAR(collectedActionPoints) select _j select 1));
// If _i is inside a cone with 20º half angle with origin on _j // If _i is inside a cone with 20º half angle with origin on _j
if (_delta select 2 > 0.94) exitWith { if (_delta select 2 > 0.94) exitWith {
@ -178,4 +169,5 @@ if (count GVAR(collectedActionPoints) > 1) then {
{ {
_x params ["_z", "_sPos", "_activeActionTree"]; _x params ["_z", "_sPos", "_activeActionTree"];
[[], _activeActionTree, _sPos, [180,360]] call FUNC(renderMenu); [[], _activeActionTree, _sPos, [180,360]] call FUNC(renderMenu);
} forEach GVAR(collectedActionPoints); nil
} count GVAR(collectedActionPoints);

View File

@ -16,88 +16,83 @@
BEGIN_COUNTER(fnc_renderBaseMenu) BEGIN_COUNTER(fnc_renderBaseMenu)
private ["_distance","_pos","_weaponDir","_ref","_sPos","_activeActionTree", "_line"];
params ["_object", "_baseActionNode"]; params ["_object", "_baseActionNode"];
_baseActionNode params ["_actionData"]; _baseActionNode params ["_actionData"];
_actionData params ["_actionName", "", "", "", "", "", "", "_positionCode", "_distance", "_params"];
_distance = _actionData select 8;
// Obtain a 3D position for the action // Obtain a 3D position for the action
_pos = if((count _this) > 2) then { private _pos = if((count _this) > 2) then {
_this select 2 _this select 2
} else { } else {
// Setup scope variables for position code // Setup scope variables for position code
private ["_target"]; private _target = _object;
_target = _object;
// Get action position // Get action position
_object modelToWorldVisual (call (_actionData select 7)) _object modelToWorldVisual (call _positionCode)
}; };
// For non-self actions, exit if the action is too far away or ocluded // For non-self actions, exit if the action is too far away or ocluded
if (GVAR(openedMenuType) == 0 && (vehicle ACE_player == ACE_player) && (isNull curatorCamera) && private _distanceToBasePoint = 0; //This will be 0 for self/zeus/in-vehicle (used later to check sub action distance)
if ((GVAR(openedMenuType) == 0) && {vehicle ACE_player == ACE_player} && {isNull curatorCamera} &&
{ {
private ["_headPos","_actualDistance"]; private _headPos = ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot");
_headPos = ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot"); _distanceToBasePoint = _headPos distance _pos;
_actualDistance = _headPos distance _pos;
if (_actualDistance > _distance) exitWith {true}; if (_distanceToBasePoint > _distance) exitWith {true};
if ((_actualDistance > 1.5) && {!((_actionData select 9) select 4)}) exitWith { if ((_distanceToBasePoint > 1.5) && {!(_params select 4)}) exitWith {
// If distance to action is greater than 1.5 m, check LOS // If distance to action is greater than 1.5 m and check isn't disabled in params, check LOS
_line = [_headPos call EFUNC(common,positionToASL), _pos call EFUNC(common,positionToASL), _object, ACE_player]; lineIntersects [AGLtoASL _headPos, AGLtoASL _pos, _object, ACE_player]
lineIntersects _line
}; };
false false
}) exitWith {false}; }) exitWith {false};
// Exit if the action is behind you // Exit if the action is behind you
_sPos = if (count _pos != 2) then { private _sPos = if (count _pos != 2) then {
worldToScreen _pos worldToScreen _pos
} else { } else {
_pos _pos
}; };
if(count _sPos == 0) exitWith {false}; if (_sPos isEqualTo []) exitWith {false};
// Exit if the action is off screen // Exit if the action is off screen
if ((_sPos select 0) < safeZoneXAbs || (_sPos select 0) > safeZoneXAbs + safeZoneWAbs) exitWith {false}; if ((_sPos select 0) < safeZoneXAbs || {(_sPos select 0) > safeZoneXAbs + safeZoneWAbs}) exitWith {false};
if ((_sPos select 1) < safeZoneY || (_sPos select 1) > safeZoneY + safeZoneH) exitWith {false}; if ((_sPos select 1) < safeZoneY || {(_sPos select 1) > safeZoneY + safeZoneH}) exitWith {false};
BEGIN_COUNTER(fnc_collectActiveActionTree) BEGIN_COUNTER(fnc_collectActiveActionTree)
// Collect active tree // Collect active tree
private "_uid"; private _uid = format [QGVAR(ATCache_%1), _actionName];
_uid = format [QGVAR(ATCache_%1), _actionData select 0]; private _activeActionTree = [
_activeActionTree = [ [_object, _baseActionNode, [], _distanceToBasePoint],
[_object, _baseActionNode, []],
DFUNC(collectActiveActionTree), DFUNC(collectActiveActionTree),
_object, _uid, 1.0, "interactMenuClosed" _object, _uid, 1.0, "interactMenuClosed"
] call EFUNC(common,cachedCall); ] call EFUNC(common,cachedCall);
END_COUNTER(fnc_collectActiveActionTree) END_COUNTER(fnc_collectActiveActionTree)
/* #ifdef DEBUG_MODE_EXTRA
diag_log "Printing: _activeActionTree"; diag_log "Printing: _activeActionTree";
_fnc_print = { [0, _activeActionTree] call {
EXPLODE_2_PVT(_this,_level,_node); params ["_level", "_node"];
EXPLODE_3_PVT(_node,_actionData,_children,_object); _node params ["_actionData", "_children", "_object"];
diag_log text format ["Level %1 -> %2 on %3", _level, _actionData select 0, _object]; diag_log text format ["Level %1 -> %2 on %3", _level, _actionData select 0, _object];
{ {
[_level + 1, _x] call _fnc_print; [_level + 1, _x] call _fnc_print;
} forEach _children; } forEach _children;
}; };
[0, _activeActionTree] call _fnc_print; #endif
*/
// Check if there's something left for rendering // Check if there's something left for rendering
if (count _activeActionTree == 0) exitWith {false}; if (_activeActionTree isEqualTo []) exitWith {false};
BEGIN_COUNTER(fnc_renderMenus); BEGIN_COUNTER(fnc_renderMenus);
// IGNORE_PRIVATE_WARNING(_cameraPos,_cameraDir); // IGNORE_PRIVATE_WARNING(_cameraPosASL,_cameraDir);
if (count _pos > 2) then { if (count _pos > 2) then {
_sPos pushBack (((_pos call EFUNC(common,positionToASL)) vectorDiff _cameraPos) vectorDotProduct _cameraDir); _sPos pushBack (((AGLtoASL _pos) vectorDiff _cameraPosASL) vectorDotProduct _cameraDir);
} else { } else {
_sPos pushBack 0; _sPos pushBack 0;
}; };

View File

@ -15,21 +15,20 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
#define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa) #define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa)
private ["_ctrl", "_pos", "_displayNum"];
params ["_text", "_icon", "_sPos", "_textSettings"]; params ["_text", "_icon", "_sPos", "_textSettings"];
//systemChat format ["Icon %1 - %2,%3", _text, _sPos select 0, _sPos select 1]; TRACE_2("Icon",_text,_sPos);
if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then { if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
_displayNum = [[46, 12] select visibleMap,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]); private _displayNum = [[46, 12] select visibleMap,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]); GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
if (GVAR(useCursorMenu)) then { if (GVAR(useCursorMenu)) then {
((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; ((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)];
((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)]; ((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseButtonDown", DFUNC(handleMouseButtonDown)];
}; };
}; };
_ctrl = GVAR(iconCtrls) select GVAR(iconCount); private _ctrl = GVAR(iconCtrls) select GVAR(iconCount);
if(_icon == "") then { if(_icon == "") then {
_icon = DEFAULT_ICON; _icon = DEFAULT_ICON;
@ -41,11 +40,10 @@ _text = if (GVAR(UseListMenu)) then {
format ["<img image='%1' align='center'/><br/><t %2 align='center'>%3</t>", _icon, _textSettings, "ace_break_line" callExtension _text]; format ["<img image='%1' align='center'/><br/><t %2 align='center'>%3</t>", _icon, _textSettings, "ace_break_line" callExtension _text];
}; };
//_ctrl ctrlSetStructuredText parseText _text;
[_ctrl, GVAR(iconCount), _text] call FUNC(ctrlSetParsedTextCached); [_ctrl, GVAR(iconCount), _text] call FUNC(ctrlSetParsedTextCached);
GVAR(iconCount) = GVAR(iconCount) + 1; GVAR(iconCount) = GVAR(iconCount) + 1;
_pos = if (GVAR(UseListMenu)) then { private _pos = if (GVAR(UseListMenu)) then {
[(_sPos select 0)-(0.0095*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.20*SafeZoneW, 0.035*SafeZoneW] [(_sPos select 0)-(0.0095*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.20*SafeZoneW, 0.035*SafeZoneW]
} else { } else {
[(_sPos select 0)-(0.0750*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.15*SafeZoneW, 0.100*SafeZoneW] [(_sPos select 0)-(0.0750*SafeZoneW), (_sPos select 1)-(0.0095*SafeZoneW), 0.15*SafeZoneW, 0.100*SafeZoneW]

View File

@ -15,22 +15,20 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private ["_menuInSelectedPath", "_path", "_menuDepth", "_x", "_offset", "_newPos", "_forEachIndex", "_player", "_pos", "_target", "_textSettings"];
params ["_parentPath", "_action", "_sPos", "_angles"]; params ["_parentPath", "_action", "_sPos", "_angles"];
_action params ["_actionData", "_activeChildren", "_actionObject"]; _action params ["_actionData", "_activeChildren", "_actionObject"];
_angles params ["_centerAngle", "_maxAngleSpan"]; _angles params ["_centerAngle", "_maxAngleSpan"];
_menuDepth = (count GVAR(menuDepthPath)); private _menuDepth = (count GVAR(menuDepthPath));
//BEGIN_COUNTER(constructing_paths); //BEGIN_COUNTER(constructing_paths);
// Store path to action // Store path to action
_path = +_parentPath; private _path = +_parentPath;
_path pushBack [_actionData select 0,_actionObject]; _path pushBack [_actionData select 0,_actionObject];
// Check if the menu is on the selected path // Check if the menu is on the selected path
_menuInSelectedPath = true; private _menuInSelectedPath = true;
{ {
if (_forEachIndex >= (count GVAR(menuDepthPath))) exitWith { if (_forEachIndex >= (count GVAR(menuDepthPath))) exitWith {
_menuInSelectedPath = false; _menuInSelectedPath = false;
@ -44,7 +42,7 @@ _menuInSelectedPath = true;
//BEGIN_COUNTER(constructing_colors); //BEGIN_COUNTER(constructing_colors);
//Get text color settings string //Get text color settings string
_textSettings = GVAR(colorSelectedSettings); private _textSettings = GVAR(colorSelectedSettings);
if(!_menuInSelectedPath) then { if(!_menuInSelectedPath) then {
_textSettings = (GVAR(textSettingsMatrix) select (count _path)) select _menuDepth; _textSettings = (GVAR(textSettingsMatrix) select (count _path)) select _menuDepth;
}; };
@ -68,13 +66,12 @@ if !(_menuInSelectedPath) exitWith {true};
//BEGIN_COUNTER(children); //BEGIN_COUNTER(children);
private ["_numChildren","_angleSpan","_angle","_angleInterval","_scaleX", "_scaleY", "_offset", "_textSize"]; private _numChildren = count _activeChildren;
_numChildren = count _activeChildren; private _angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1));
_angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1));
if (_angleSpan >= 305) then { if (_angleSpan >= 305) then {
_angleSpan = 360; _angleSpan = 360;
}; };
_angleInterval = 55; private _angleInterval = 55;
if (_angleSpan < 360) then { if (_angleSpan < 360) then {
if (_numChildren > 1) then { if (_numChildren > 1) then {
_angleInterval = _angleSpan / (_numChildren - 1); _angleInterval = _angleSpan / (_numChildren - 1);
@ -87,15 +84,15 @@ if (_numChildren == 1) then {
}; };
// Scale menu based on the amount of children // Scale menu based on the amount of children
_scaleX = 1; private _scaleX = 1;
_scaleY = 1; private _scaleY = 1;
if (GVAR(UseListMenu)) then { if (GVAR(UseListMenu)) then {
_textSize = [0.75, 0.875, 1, 1.2, 1.4] select GVAR(textSize); private _textSize = [0.75, 0.875, 1, 1.2, 1.4] select GVAR(textSize);
_scaleX = _textSize * 0.17 * 1.1; _scaleX = _textSize * 0.17 * 1.1;
_scaleY = 0.17 * 0.30 * 4/3; _scaleY = 0.17 * 0.30 * 4/3;
} else { } else {
_textSize = if (GVAR(textSize) > 2) then {1.3} else {1}; private _textSize = if (GVAR(textSize) > 2) then {1.3} else {1};
_scaleX = _textSize * 0.17 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5); _scaleX = _textSize * 0.17 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5);
_scaleY = _textSize * 0.17 * 4/3 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5); _scaleY = _textSize * 0.17 * 4/3 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5);
}; };
@ -106,15 +103,13 @@ if (_menuInSelectedPath && {_menuDepth == count _path}) then {
_scaleY = _scaleY * (0.3 + 0.7 * (((ACE_diagTime - GVAR(expandedTime)) * linearConversion [0, 2, GVAR(menuAnimationSpeed), 8, 16]) min 1)); _scaleY = _scaleY * (0.3 + 0.7 * (((ACE_diagTime - GVAR(expandedTime)) * linearConversion [0, 2, GVAR(menuAnimationSpeed), 8, 16]) min 1));
}; };
_target = _actionObject; private _target = _actionObject;
_player = ACE_player; private _player = ACE_player;
//END_COUNTER(children); //END_COUNTER(children);
_angle = _centerAngle - _angleSpan / 2; private _angle = _centerAngle - _angleSpan / 2;
{ {
//BEGIN_COUNTER(children); private _newPos = if (GVAR(UseListMenu)) then {
private ["_offset","_newPos"];
_newPos = if (GVAR(UseListMenu)) then {
[(_sPos select 0) + _scaleX, [(_sPos select 0) + _scaleX,
(_sPos select 1) + _scaleY * (_forEachIndex - _numChildren/2 + 0.5)]; (_sPos select 1) + _scaleY * (_forEachIndex - _numChildren/2 + 0.5)];
} else { } else {
@ -122,8 +117,6 @@ _angle = _centerAngle - _angleSpan / 2;
(_sPos select 1) + _scaleY * (sin _angle)]; (_sPos select 1) + _scaleY * (sin _angle)];
}; };
//drawLine3D [_pos, _newPos, [1,0,0,0.8]];
//END_COUNTER(children);
[_path, _x, _newPos, [_angle, 150]] call FUNC(renderMenu); [_path, _x, _newPos, [_angle, 150]] call FUNC(renderMenu);
_angle = _angle + _angleInterval; _angle = _angle + _angleInterval;

View File

@ -15,10 +15,8 @@
params ["_sPos", "_icon"]; params ["_sPos", "_icon"];
private ["_displayNum", "_ctrl", "_pos"];
if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then { if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
_displayNum = [[46, 12] select visibleMap,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]); private _displayNum = [[46, 12] select visibleMap,91919] select (uiNamespace getVariable [QGVAR(cursorMenuOpened),false]);
GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]); GVAR(iconCtrls) pushBack ((findDisplay _displayNum) ctrlCreate ["RscStructuredText", 54021+GVAR(iconCount)]);
if (GVAR(useCursorMenu)) then { if (GVAR(useCursorMenu)) then {
((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)]; ((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)];
@ -26,9 +24,9 @@ if(GVAR(iconCount) > (count GVAR(iconCtrls))-1) then {
}; };
}; };
_ctrl = GVAR(iconCtrls) select GVAR(iconCount); private _ctrl = GVAR(iconCtrls) select GVAR(iconCount);
_pos = if (GVAR(UseListMenu)) then { private _pos = if (GVAR(UseListMenu)) then {
[_ctrl, GVAR(iconCount), format ["<img image='%1' color='#FF0000' size='1.6'/>", _icon]] call FUNC(ctrlSetParsedTextCached); [_ctrl, GVAR(iconCount), format ["<img image='%1' color='#FF0000' size='1.6'/>", _icon]] call FUNC(ctrlSetParsedTextCached);
[(_sPos select 0)-(0.014*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.05*SafeZoneW, 0.035*SafeZoneW] [(_sPos select 0)-(0.014*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.05*SafeZoneW, 0.035*SafeZoneW]
} else { } else {

View File

@ -12,15 +12,13 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private ["_menuDepth", "_mixColor", "_pathCount", "_row", "_shadowColor", "_textColor", "_textSize", "_colorShadowMax", "_colorShadowMin", "_colorTextMax", "_colorTextMin", "_shadowSetting"];
//Mixes 2 colors (number arrays) and makes a color string "#AARRGGBB" for structured text //Mixes 2 colors (number arrays) and makes a color string "#AARRGGBB" for structured text
_mixColor = { private _mixColor = {
params ["_color1", "_color2", "_ratio"]; params ["_color1", "_color2", "_ratio"];
private ["_return", "_mix", "_index"];
_return = ""; private _return = "";
for "_index" from 0 to 3 do { for "_index" from 0 to 3 do {
_mix = linearConversion [0, 1, _ratio, (_color1 select _index), (_color2 select _index)]; private _mix = linearConversion [0, 1, _ratio, (_color1 select _index), (_color2 select _index)];
if (_index != 3) then { if (_index != 3) then {
_return = _return + ([255 * _mix] call EFUNC(common,toHex)); _return = _return + ([255 * _mix] call EFUNC(common,toHex));
} else { } else {
@ -30,15 +28,17 @@ _mixColor = {
_return _return
}; };
_colorTextMin = missionNamespace getVariable [QGVAR(colorTextMin), [1,1,1,0.25]]; private _colorTextMin = missionNamespace getVariable [QGVAR(colorTextMin), [1,1,1,0.25]];
_colorTextMax = missionNamespace getVariable [QGVAR(colorTextMax), [1,1,1,1]]; private _colorTextMax = missionNamespace getVariable [QGVAR(colorTextMax), [1,1,1,1]];
_colorShadowMin = missionNamespace getVariable [QGVAR(colorShadowMin), [0,0,0,0.25]]; private _colorShadowMin = missionNamespace getVariable [QGVAR(colorShadowMin), [0,0,0,0.25]];
_colorShadowMax = missionNamespace getVariable [QGVAR(colorShadowMax), [0,0,0,1]]; private _colorShadowMax = missionNamespace getVariable [QGVAR(colorShadowMax), [0,0,0,1]];
_shadowSetting = missionNamespace getVariable [QGVAR(shadowSetting), 2]; private _shadowSetting = missionNamespace getVariable [QGVAR(shadowSetting), 2];
_textSize = missionNamespace getVariable [QGVAR(textSize), 2]; private _textSize = missionNamespace getVariable [QGVAR(textSize), 2];
_textColor = [_colorTextMin, _colorTextMax, 1] call _mixColor; TRACE_6("Building text matrix",_colorTextMin,_colorTextMax,_colorShadowMin,_colorShadowMax,_shadowSetting,_textSize);
_shadowColor = [_colorShadowMin, _colorShadowMax, 1] call _mixColor;
private _textColor = [_colorTextMin, _colorTextMax, 1] call _mixColor;
private _shadowColor = [_colorShadowMin, _colorShadowMax, 1] call _mixColor;
_textSize = switch (_textSize) do { _textSize = switch (_textSize) do {
case (0): {0.4}; case (0): {0.4};
case (1): {0.6}; case (1): {0.6};
@ -51,7 +51,7 @@ GVAR(colorSelectedSettings) = format ["color='%1' size='%2' shadow='%3' shadowCo
GVAR(textSettingsMatrix) = []; GVAR(textSettingsMatrix) = [];
for "_pathCount" from 0 to 15 do { for "_pathCount" from 0 to 15 do {
_row = []; private _row = [];
for "_menuDepth" from 0 to 15 do { for "_menuDepth" from 0 to 15 do {
if (_menuDepth > 0) then { if (_menuDepth > 0) then {
_textColor = [_colorTextMin, _colorTextMax, (((_pathCount - 1) / _menuDepth) max 0.25)] call _mixColor; _textColor = [_colorTextMin, _colorTextMax, (((_pathCount - 1) / _menuDepth) max 0.25)] call _mixColor;

View File

@ -13,12 +13,11 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private ["_parentPath","_actionName", "_i"]; private _parentPath = [];
_parentPath = []; for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do {
for [{_i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do {
_parentPath pushBack (_this select _i); _parentPath pushBack (_this select _i);
}; };
_actionName = if (count _this > 0) then { private _actionName = if (count _this > 0) then {
_this select ((count _this) - 1); _this select ((count _this) - 1);
} else { } else {
"" ""

View File

@ -1,7 +1,7 @@
/* /*
* Author: PabstMirror * Author: PabstMirror
* Scans for nearby "Static" objects (buildings) and adds the UserActions to them. * Scans for nearby "Static" objects (buildings) and adds the UserActions to them.
* Called when interact_menu starts rendering (from "interact_keyDown" event) * Called when interact_menu starts rendering (from "interactMenuOpened" event)
* *
* Arguments: * Arguments:
* 0: Interact Menu Type (0 - world, 1 - self) <NUMBER> * 0: Interact Menu Type (0 - world, 1 - self) <NUMBER>
@ -10,9 +10,9 @@
* Nothing * Nothing
* *
* Example: * Example:
* [0] call ace_interact_menu_fnc_addHouseActions * [0] call ace_interact_menu_fnc_userActions_addHouseActions
* *
* Public: Yes * Public: No
*/ */
#include "script_component.hpp" #include "script_component.hpp"
@ -26,7 +26,6 @@ if (_interactionType != 0) exitWith {};
if ((vehicle ACE_player) != ACE_player) exitWith {}; if ((vehicle ACE_player) != ACE_player) exitWith {};
[{ [{
private ["_nearBuidlings", "_typeOfHouse", "_houseBeingScaned", "_actionSet", "_memPoints", "_memPointsActions", "_helperPos", "_helperObject"];
params ["_args", "_pfID"]; params ["_args", "_pfID"];
_args params ["_setPosition", "_addedHelpers", "_housesScaned", "_housesToScanForActions"]; _args params ["_setPosition", "_addedHelpers", "_housesScaned", "_housesToScanForActions"];
@ -54,33 +53,34 @@ if ((vehicle ACE_player) != ACE_player) exitWith {};
//If player moved >2 meters from last pos, then rescan //If player moved >2 meters from last pos, then rescan
if (((getPosASL ace_player) distance _setPosition) < 2) exitWith {}; if (((getPosASL ace_player) distance _setPosition) < 2) exitWith {};
_nearBuidlings = nearestObjects [ace_player, ["Static"], 30]; private _nearBuidlings = nearestObjects [ace_player, ["Static"], 30];
{ {
_typeOfHouse = typeOf _x; private _typeOfHouse = typeOf _x;
if (((count (configFile >> "CfgVehicles" >> _typeOfHouse >> "UserActions")) == 0) && {(count (getArray (configFile >> "CfgVehicles" >> _typeOfHouse >> "ladders"))) == 0}) then { if (((count (configFile >> "CfgVehicles" >> _typeOfHouse >> "UserActions")) == 0) && {(count (getArray (configFile >> "CfgVehicles" >> _typeOfHouse >> "ladders"))) == 0}) then {
_housesScaned pushBack _x; _housesScaned pushBack _x;
} else { } else {
_housesToScanForActions pushBack _x; _housesToScanForActions pushBack _x;
}; };
} forEach (_nearBuidlings - _housesScaned); nil
} count (_nearBuidlings - _housesScaned);
_args set [0, (getPosASL ace_player)]; _args set [0, (getPosASL ace_player)];
} else { } else {
_houseBeingScaned = _housesToScanForActions deleteAt 0; _houseBeingScaned = _housesToScanForActions deleteAt 0;
_typeOfHouse = typeOf _houseBeingScaned; private _typeOfHouse = typeOf _houseBeingScaned;
//Skip this house for now if we are outside of it's radius //Skip this house for now if we are outside of it's radius
//(we have to scan far out for the big houses, but we don't want to waste time adding actions on every little shack) //(we have to scan far out for the big houses, but we don't want to waste time adding actions on every little shack)
if ((_houseBeingScaned != cursorTarget) && {((ACE_player distance _houseBeingScaned) - ((sizeOf _typeOfHouse) / 2)) > 4}) exitWith {}; if ((_houseBeingScaned != cursorTarget) && {((ACE_player distance _houseBeingScaned) - ((sizeOf _typeOfHouse) / 2)) > 4}) exitWith {};
_housesScaned pushBack _houseBeingScaned; _housesScaned pushBack _houseBeingScaned;
_actionSet = [_typeOfHouse] call FUNC(userActions_getHouseActions); private _actionSet = [_typeOfHouse] call FUNC(userActions_getHouseActions);
_actionSet params ["_memPoints", "_memPointsActions"]; _actionSet params ["_memPoints", "_memPointsActions"];
// systemChat format ["Add Actions for [%1] (count %2) @ %3", _typeOfHouse, (count _memPoints), diag_tickTime]; // systemChat format ["Add Actions for [%1] (count %2) @ %3", _typeOfHouse, (count _memPoints), diag_tickTime];
{ {
_helperPos = (_houseBeingScaned modelToWorld (_houseBeingScaned selectionPosition _x)) call EFUNC(common,positionToASL); private _helperPos = AGLtoASL (_houseBeingScaned modelToWorld (_houseBeingScaned selectionPosition _x));
_helperObject = "ACE_LogicDummy" createVehicleLocal _helperPos; private _helperObject = "ACE_LogicDummy" createVehicleLocal _helperPos;
_addedHelpers pushBack _helperObject; _addedHelpers pushBack _helperObject;
_helperObject setVariable [QGVAR(building), _houseBeingScaned]; _helperObject setVariable [QGVAR(building), _houseBeingScaned];
_helperObject setPosASL _helperPos; _helperObject setPosASL _helperPos;
@ -88,9 +88,11 @@ if ((vehicle ACE_player) != ACE_player) exitWith {};
{ {
[_helperObject, 0, [], _x] call EFUNC(interact_menu,addActionToObject); [_helperObject, 0, [], _x] call EFUNC(interact_menu,addActionToObject);
} forEach (_memPointsActions select _forEachIndex); nil
} count (_memPointsActions select _forEachIndex);
} forEach _memPoints;
nil
} count _memPoints;
}; };
}; };
}, 0, [((getPosASL ace_player) vectorAdd [-100,0,0]), [], [], []]] call CBA_fnc_addPerFrameHandler; }, 0, [((getPosASL ace_player) vectorAdd [-100,0,0]), [], [], []]] call CBA_fnc_addPerFrameHandler;

View File

@ -8,22 +8,23 @@
* Return Value: * Return Value:
* [[Array of MemPoints], [Array Of Actions]] * [[Array of MemPoints], [Array Of Actions]]
* *
* Public: Yes * Example:
* ["Land_i_House_Big_01_V1_F"] call ace_interact_menu_fnc_userActions_getHouseActions
*
* Public: No
*/ */
#include "script_component.hpp" #include "script_component.hpp"
params ["_typeOfBuilding"]; params ["_typeOfBuilding"];
private["_action", "_actionDisplayName", "_actionDisplayNameDefault", "_actionMaxDistance", "_actionOffset", "_actionPath", "_actionPosition", "_building", "_configPath", "_endIndex", "_iconImage", "_index", "_ladders", "_memPointIndex", "_memPoints", "_memPointsActions", "_startIndex"]; private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding;
_searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding;
if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex}; if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex};
_memPoints = []; private _memPoints = [];
_memPointsActions = []; private _memPointsActions = [];
//Get the offset for a memory point: //Get the offset for a memory point:
_fnc_getMemPointOffset = { private _fnc_getMemPointOffset = {
params ["_memoryPoint"]; params ["_memoryPoint"];
_memPointIndex = _memPoints find _memoryPoint; _memPointIndex = _memPoints find _memoryPoint;
_actionOffset = [0,0,0]; _actionOffset = [0,0,0];
@ -37,13 +38,13 @@ _fnc_getMemPointOffset = {
}; };
// Add UserActions for the building: // Add UserActions for the building:
_fnc_userAction_Statement = { private _fnc_userAction_Statement = {
params ["_target", "_player", "_variable"]; params ["_target", "_player", "_variable"];
_variable params ["_actionStatement", "_actionCondition"]; _variable params ["_actionStatement", "_actionCondition"];
this = _target getVariable [QGVAR(building), objNull]; this = _target getVariable [QGVAR(building), objNull];
call _actionStatement; call _actionStatement;
}; };
_fnc_userAction_Condition = { private _fnc_userAction_Condition = {
params ["_target", "_player", "_variable"]; params ["_target", "_player", "_variable"];
_variable params ["_actionStatement", "_actionCondition"]; _variable params ["_actionStatement", "_actionCondition"];
this = _target getVariable [QGVAR(building), objNull]; this = _target getVariable [QGVAR(building), objNull];
@ -51,16 +52,16 @@ _fnc_userAction_Condition = {
call _actionCondition; call _actionCondition;
}; };
_configPath = configFile >> "CfgVehicles" >> _typeOfBuilding >> "UserActions"; private _configPath = configFile >> "CfgVehicles" >> _typeOfBuilding >> "UserActions";
for "_index" from 0 to ((count _configPath) - 1) do { for "_index" from 0 to ((count _configPath) - 1) do {
_actionPath = _configPath select _index; private _actionPath = _configPath select _index;
_actionDisplayName = getText (_actionPath >> "displayName"); private _actionDisplayName = getText (_actionPath >> "displayName");
_actionDisplayNameDefault = getText (_actionPath >> "displayNameDefault"); private _actionDisplayNameDefault = getText (_actionPath >> "displayNameDefault");
_actionPosition = getText (_actionPath >> "position"); private _actionPosition = getText (_actionPath >> "position");
_actionCondition = getText (_actionPath >> "condition"); private _actionCondition = getText (_actionPath >> "condition");
_actionStatement = getText (_actionPath >> "statement"); private _actionStatement = getText (_actionPath >> "statement");
_actionMaxDistance = getNumber (_actionPath >> "radius"); private _actionMaxDistance = getNumber (_actionPath >> "radius");
if (_actionDisplayName == "") then {_actionDisplayName = (configName _x);}; if (_actionDisplayName == "") then {_actionDisplayName = (configName _x);};
if (_actionPosition == "") then {ERROR("Bad Position");}; if (_actionPosition == "") then {ERROR("Bad Position");};
@ -70,53 +71,52 @@ for "_index" from 0 to ((count _configPath) - 1) do {
_actionStatement = compile _actionStatement; _actionStatement = compile _actionStatement;
_actionCondition = compile _actionCondition; _actionCondition = compile _actionCondition;
_actionMaxDistance = _actionMaxDistance + 0.1; //increase range slightly _actionMaxDistance = _actionMaxDistance + 0.1; //increase range slightly
_iconImage = "";
//extension ~4x as fast: //extension ~4x as fast:
_iconImage = "ace_parse_imagepath" callExtension _actionDisplayNameDefault; private _iconImage = "ace_parse_imagepath" callExtension _actionDisplayNameDefault;
_actionOffset = [_actionPosition] call _fnc_getMemPointOffset; private _actionOffset = [_actionPosition] call _fnc_getMemPointOffset;
_memPointIndex = _memPoints find _actionPosition; private _memPointIndex = _memPoints find _actionPosition;
_action = [(configName _actionPath), _actionDisplayName, _iconImage, _fnc_userAction_Statement, _fnc_userAction_Condition, {}, [_actionStatement, _actionCondition], _actionOffset, _actionMaxDistance, [false,false,false,false,true]] call EFUNC(interact_menu,createAction); _action = [(configName _actionPath), _actionDisplayName, _iconImage, _fnc_userAction_Statement, _fnc_userAction_Condition, {}, [_actionStatement, _actionCondition], _actionOffset, _actionMaxDistance, [false,false,false,false,true]] call EFUNC(interact_menu,createAction);
(_memPointsActions select _memPointIndex) pushBack _action; (_memPointsActions select _memPointIndex) pushBack _action;
}; };
// Add Ladder Actions for the building: // Add Ladder Actions for the building:
_fnc_ladder_ladderUp = { private _fnc_ladder_ladderUp = {
params ["_target", "_player", "_variable"]; params ["_target", "_player", "_variable"];
_variable params ["_ladderIndex"]; _variable params ["_ladderIndex"];
_building = _target getVariable [QGVAR(building), objNull]; private _building = _target getVariable [QGVAR(building), objNull];
TRACE_3("Ladder Action - UP",_player,_building,_ladderIndex); TRACE_3("Ladder Action - UP",_player,_building,_ladderIndex);
_player action ["LadderUp", _building, _ladderIndex, 0]; _player action ["LadderUp", _building, _ladderIndex, 0];
}; };
_fnc_ladder_ladderDown = { private _fnc_ladder_ladderDown = {
params ["_target", "_player", "_variable"]; params ["_target", "_player", "_variable"];
_variable params ["_ladderIndex"]; _variable params ["_ladderIndex"];
_building = _target getVariable [QGVAR(building), objNull]; private _building = _target getVariable [QGVAR(building), objNull];
TRACE_3("Ladder Action - Down",_player,_building,_ladderIndex); TRACE_3("Ladder Action - Down",_player,_building,_ladderIndex);
_player action ["LadderDown", _building, _ladderIndex, 1]; _player action ["LadderDown", _building, _ladderIndex, 1];
}; };
_fnc_ladder_conditional = { private _fnc_ladder_conditional = {
params ["_target", "_player"]; params ["_target", "_player"];
//(Check distance < 2) and (Don't show actions if on a ladder) //(Check distance < 2) and (Don't show actions if on a ladder)
((_target distance _player) < 2) && {((getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> (animationState _player) >> "onLadder")) == 0)} ((_target distance _player) < 2) && {((getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> (animationState _player) >> "onLadder")) == 0)}
}; };
_ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> "ladders"); private _ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> "ladders");
{ {
_x params ["_ladderBottomMemPoint", "_ladderTopMemPoint"]; _x params ["_ladderBottomMemPoint", "_ladderTopMemPoint"];
_actionMaxDistance = 3; //interact_menu will check head -> target's offset; leave this high and do a precice distance check in condition private _actionMaxDistance = 3; //interact_menu will check head -> target's offset; leave this high and do a precice distance check in condition
_actionDisplayName = localize "str_action_ladderup"; private _actionDisplayName = localize "str_action_ladderup";
_iconImage = "\A3\ui_f\data\igui\cfg\actions\ladderup_ca.paa"; private _iconImage = "\A3\ui_f\data\igui\cfg\actions\ladderup_ca.paa";
//Ladder Up Action: //Ladder Up Action:
_actionOffset = [_ladderBottomMemPoint] call _fnc_getMemPointOffset; private _actionOffset = [_ladderBottomMemPoint] call _fnc_getMemPointOffset;
_actionOffset = _actionOffset vectorAdd [0,0,1]; _actionOffset = _actionOffset vectorAdd [0,0,1];
_memPointIndex = _memPoints find _ladderBottomMemPoint; private _memPointIndex = _memPoints find _ladderBottomMemPoint;
_action = [format ["LadderUp_%1", _forEachIndex], _actionDisplayName, _iconImage, _fnc_ladder_ladderUp, _fnc_ladder_conditional, {}, [_forEachIndex], _actionOffset, _actionMaxDistance, [false,false,false,false,true]] call EFUNC(interact_menu,createAction); private _action = [format ["LadderUp_%1", _forEachIndex], _actionDisplayName, _iconImage, _fnc_ladder_ladderUp, _fnc_ladder_conditional, {}, [_forEachIndex], _actionOffset, _actionMaxDistance, [false,false,false,false,true]] call EFUNC(interact_menu,createAction);
(_memPointsActions select _memPointIndex) pushBack _action; (_memPointsActions select _memPointIndex) pushBack _action;
_actionDisplayName = localize "str_action_ladderdown"; _actionDisplayName = localize "str_action_ladderdown";

View File

@ -12,5 +12,3 @@
#endif #endif
#include "\z\ace\addons\main\script_macros.hpp" #include "\z\ace\addons\main\script_macros.hpp"
#define ENABLE_PERFORMANCE_COUNTERS