This commit is contained in:
SzwedzikPL 2016-01-22 09:20:47 +01:00
commit 9ee76742c6
32 changed files with 396 additions and 368 deletions

View File

@ -0,0 +1,16 @@
//Create a location type that won't be drawn on the map
//Ref: https://community.bistudio.com/wiki/Location
class CfgLocationTypes {
class ACE_HashLocation {
color[] = {0,0,0,0};
drawStyle = "bananas";
font = "PuristaMedium";
importance = 5;
name = "HashLocation";
shadow = 0;
size = 0;
textSize = 0.0;
texture = "";
};
};

View File

@ -14,6 +14,7 @@ class CfgPatches {
#include "CfgEventHandlers.hpp"
#include "CfgLocationTypes.hpp"
#include "CfgSounds.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"

View File

@ -9,4 +9,8 @@ if(isServer) then {
[QGVAR(frag_eh), { _this call FUNC(frago); }] call EFUNC(common,addEventHandler);
};
[FUNC(masterPFH), 0, []] call CBA_fnc_addPerFrameHandler;
[FUNC(masterPFH), 0, []] call CBA_fnc_addPerFrameHandler;
//Cache for ammo type configs
GVAR(cacheRoundsTypesToTrack) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0];
GVAR(cacheRoundsTypesToTrack) setText QGVAR(cacheRoundsTypesToTrack);

View File

@ -1,8 +1,56 @@
/*
* Author: nou, jaynus, PabstMirror
* Called from FiredBIS event on AllVehicles
* If spall is not enabled (default), then cache and only track those that will actually trigger fragmentation.
*
* Arguments:
* 0: gun - Object the event handler is assigned to <OBJECT>
* 4: type - Ammo used <STRING>
* 6: round - Object of the projectile that was shot <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [clientFiredBIS-XEH] call ace_frag_fnc_fired
*
* Public: No
*/
// #define DEBUG_ENABLED_FRAG
#include "script_component.hpp"
private["_gun", "_type", "_round"];
_gun = _this select 0;
_type = _this select 4;
_round = _this select 6;
params ["_gun", "", "", "", "_type", "", "_round"];
[_gun, _type, _round] call FUNC(addPfhRound);
private _shouldAdd = GVAR(cacheRoundsTypesToTrack) getVariable _type;
if (isNil "_shouldAdd") then {
TRACE_1("no cache for round",_type);
if (!EGVAR(common,settingsInitFinished)) exitWith {
//Just incase fired event happens before settings init, don't want to set cache wrong if spall setting changes
TRACE_1("Settings not init yet - exit without setting cache",_type);
_shouldAdd = false;
};
if (GVAR(SpallEnabled)) exitWith {
//Always want to run whenever spall is enabled?
_shouldAdd = true;
TRACE_2("SettingCache[spallEnabled]",_type,_shouldAdd);
GVAR(cacheRoundsTypesToTrack) setVariable [_type, _shouldAdd];
};
//Read configs and test if it would actually cause a frag, using same logic as FUNC(pfhRound)
private _skip = getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip));
private _explosive = getNumber (configFile >> "CfgAmmo" >> _type >> "explosive");
private _indirectRange = getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange");
private _force = getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force));
private _fragPower = getNumber(configFile >> "CfgAmmo" >> _type >> "indirecthit")*(sqrt((getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"))));
_shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}};
TRACE_6("SettingCache[willFrag?]",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd);
GVAR(cacheRoundsTypesToTrack) setVariable [_type, _shouldAdd];
};
if (_shouldAdd) then {
TRACE_3("Running Frag Tracking",_gun,_type,_round);
[_gun, _type, _round] call FUNC(addPfhRound);
};

View File

@ -18,36 +18,27 @@ class CfgWeapons {
GVAR(protection) = 1;
GVAR(lowerVolume) = 0.80;
};
class H_HelmetCrew_0: H_HelmetCrew_B {};
class H_HelmetCrew_I: H_HelmetCrew_B {};
class H_CrewHelmetHeli_B: H_HelmetB {
GVAR(protection) = 0.85;
GVAR(lowerVolume) = 0.75;
};
class H_CrewHelmetHeli_O: H_CrewHelmetHeli_B {};
class H_CrewHelmetHeli_I: H_CrewHelmetHeli_B {};
class H_PilotHelmetHeli_B: H_HelmetB {
GVAR(protection) = 0.85;
GVAR(lowerVolume) = 0.75;
};
class H_PilotHelmetHeli_O: H_PilotHelmetHeli_B {};
class H_PilotHelmetHeli_I: H_PilotHelmetHeli_B {};
class H_PilotHelmetFighter_B: H_HelmetB {
GVAR(protection) = 1;
GVAR(lowerVolume) = 0.80;
};
class H_PilotHelmetFighter_O: H_PilotHelmetFighter_B {};
class H_PilotHelmetFighter_I: H_PilotHelmetFighter_B {};
class HelmetBase;
class H_Cap_headphones: HelmetBase {
GVAR(protection) = 0.5;
GVAR(lowerVolume) = 0.60;
};
class H_Cap_marshal: H_Cap_headphones {};
class H_HelmetB_light: H_HelmetB {
GVAR(protection) = 0.8;

View File

@ -79,8 +79,7 @@ GVAR(ParsedTextCached) = [];
//Debug to help end users identify mods that break CBA's XEH
[{
private ["_badClassnames"];
_badClassnames = [];
private _badClassnames = [];
{
//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 {

View File

@ -74,11 +74,6 @@ GVAR(collectedActionPoints) = [];
GVAR(foundActions) = [];
GVAR(lastTimeSearchedActions) = -1000;
// Init CAManBase menus
["CAManBase"] call FUNC(compileMenu);
["CAManBase"] call FUNC(compileMenuSelfAction);
// Init zeus menu
[] call FUNC(compileMenuZeus);

View File

@ -30,9 +30,8 @@ if (_typeNum == 0) then {
[_objectType] call FUNC(compileMenuSelfAction);
};
private ["_varName","_actionTrees", "_parentNode"];
_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType];
_actionTrees = missionNamespace getVariable [_varName, []];
private _varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType];
private _actionTrees = missionNamespace getVariable [_varName, []];
if((count _actionTrees) == 0) then {
missionNamespace setVariable [_varName, _actionTrees];
};
@ -41,7 +40,7 @@ if (_parentPath isEqualTo ["ACE_MainActions"]) then {
[_objectType, _typeNum] call FUNC(addMainAction);
};
_parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode);
private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode);
if (isNil {_parentNode}) exitWith {
ERROR("Failed to add action");
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");
};
private ["_varName","_actionList"];
_varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum;
_actionList = _object getVariable [_varName, []];
if((count _actionList) == 0) then {
private _varName = [QGVAR(actions),QGVAR(selfActions)] select _typeNum;
private _actionList = _object getVariable [_varName, []];
if (_actionList isEqualTo []) then {
_object setVariable [_varName, _actionList];
};

View File

@ -18,14 +18,12 @@
params ["_objectType", "_typeNum"];
private["_actionTrees", "_mainAction", "_parentNode", "_varName"];
_varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType];
_actionTrees = missionNamespace getVariable [_varName, []];
_parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode);
private _varName = format [[QGVAR(Act_%1), QGVAR(SelfAct_%1)] select _typeNum, _objectType];
private _actionTrees = missionNamespace getVariable [_varName, []];
private _parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode);
if (isNil {_parentNode}) then {
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);
};

View File

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

View File

@ -14,34 +14,31 @@
params ["_target"];
private ["_objectType","_actionsVarName","_isMan"];
_objectType = _target;
_isMan = false;
private _objectType = _target;
if (_target isEqualType objNull) then {
_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
if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc";
_recurseFnc = {
private ["_actions", "_displayName", "_distance", "_icon", "_statement", "_position", "_condition", "_showDisabled", "_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction"];
params ["_actionsCfg"];
_actions = [];
private _recurseFnc = {
params ["_actionsCfg", "_parentDistance"];
private _actions = [];
{
_entryCfg = _x;
private _entryCfg = _x;
if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName");
_distance = getNumber (_entryCfg >> "distance");
_icon = getText (_entryCfg >> "icon");
_statement = compile (getText (_entryCfg >> "statement"));
private _displayName = getText (_entryCfg >> "displayName");
private _distance = _parentDistance;
if (isNumber (_entryCfg >> "distance")) then {_distance = getNumber (_entryCfg >> "distance");};
// 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
_position = getText (_entryCfg >> "position");
private _position = getText (_entryCfg >> "position");
if (_position != "") then {
_position = compile _position;
} else {
@ -55,7 +52,7 @@ _recurseFnc = {
};
};
_condition = getText (_entryCfg >> "condition");
private _condition = getText (_entryCfg >> "condition");
if (_condition == "") then {_condition = "true"};
// Add canInteract (including exceptions) and canInteractWith to condition
@ -63,13 +60,13 @@ _recurseFnc = {
_condition = _condition + format [QUOTE( && {[ARR_3(ACE_player, _target, %1)] call EFUNC(common,canInteractWith)} ), getArray (_entryCfg >> "exceptions")];
};
_insertChildren = compile (getText (_entryCfg >> "insertChildren"));
_modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
private _insertChildren = compile (getText (_entryCfg >> "insertChildren"));
private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
_showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
_enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
_canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
_runOnHover = false;
private _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
private _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
private _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
private _runOnHover = false;
if (isText (_entryCfg >> "runOnHover")) then {
_runOnHover = compile getText (_entryCfg >> "runOnHover");
} else {
@ -77,9 +74,9 @@ _recurseFnc = {
};
_condition = compile _condition;
_children = [_entryCfg] call _recurseFnc;
private _children = [_entryCfg, _distance] call _recurseFnc;
_entry = [
private _entry = [
[
configName _entryCfg,
_displayName,
@ -97,19 +94,16 @@ _recurseFnc = {
];
_actions pushBack _entry;
};
} forEach (configProperties [_actionsCfg, "isClass _x", true]);
nil
} count (configProperties [_actionsCfg, "isClass _x", true]);
_actions
};
private ["_actionsCfg","_actions"];
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions";
private _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_Actions";
TRACE_1("Building ACE_Actions",_objectType);
private _actions = [_actionsCfg, 0] call _recurseFnc;
// If the classname inherits from CAManBase, just copy it's menu without recompiling a new one
_actions = if (_isMan) then {
+ (missionNamespace getVariable QGVAR(Act_CAManBase))
} else {
[_actionsCfg] call _recurseFnc
};
missionNamespace setVariable [_actionsVarName, _actions];
/*
@ -125,7 +119,7 @@ missionNamespace setVariable [_actionsVarName, _actions];
[],
{[0,0,0]},
1,
[false,false,false]
[false,false,false,false,false]
],
[children actions]
]

View File

@ -14,46 +14,42 @@
params ["_target"];
private ["_objectType","_actionsVarName","_isMan"];
_objectType = _target;
_isMan = false;
private _objectType = _target;
if (_target isEqualType objNull) then {
_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
if !(isNil {missionNamespace getVariable [_actionsVarName, nil]}) exitWith {};
private "_recurseFnc";
_recurseFnc = {
private ["_actions", "_displayName", "_icon", "_statement", "_condition", "_showDisabled",
"_enableInside", "_canCollapse", "_runOnHover", "_children", "_entry", "_entryCfg", "_insertChildren", "_modifierFunction"];
private _recurseFnc = {
params ["_actionsCfg"];
_actions = [];
private _actions = [];
{
_entryCfg = _x;
private _entryCfg = _x;
if(isClass _entryCfg) then {
_displayName = getText (_entryCfg >> "displayName");
private _displayName = getText (_entryCfg >> "displayName");
_icon = getText (_entryCfg >> "icon");
_statement = compile (getText (_entryCfg >> "statement"));
private _icon = getText (_entryCfg >> "icon");
private _statement = compile (getText (_entryCfg >> "statement"));
_condition = getText (_entryCfg >> "condition");
private _condition = getText (_entryCfg >> "condition");
if (_condition == "") then {_condition = "true"};
// 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")];
_insertChildren = compile (getText (_entryCfg >> "insertChildren"));
_modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
private _insertChildren = compile (getText (_entryCfg >> "insertChildren"));
private _modifierFunction = compile (getText (_entryCfg >> "modifierFunction"));
_showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
_enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
_canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
_runOnHover = true;
private _showDisabled = (getNumber (_entryCfg >> "showDisabled")) > 0;
private _enableInside = (getNumber (_entryCfg >> "enableInside")) > 0;
private _canCollapse = (getNumber (_entryCfg >> "canCollapse")) > 0;
private _runOnHover = true;
if (isText (_entryCfg >> "runOnHover")) then {
_runOnHover = compile getText (_entryCfg >> "runOnHover");
} else {
@ -61,9 +57,9 @@ _recurseFnc = {
};
_condition = compile _condition;
_children = [_entryCfg] call _recurseFnc;
private _children = [_entryCfg] call _recurseFnc;
_entry = [
private _entry = [
[
configName _entryCfg,
_displayName,
@ -81,16 +77,15 @@ _recurseFnc = {
];
_actions pushBack _entry;
};
} forEach (configProperties [_actionsCfg, "isClass _x", true]);
nil
} count (configProperties [_actionsCfg, "isClass _x", true]);
_actions
};
private ["_actionsCfg","_actions"];
_actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
private _actionsCfg = configFile >> "CfgVehicles" >> _objectType >> "ACE_SelfActions";
private ["_baseDisplayName", "_baseIcon"];
_baseDisplayName = "";
_baseIcon = "";
private _baseDisplayName = "";
private _baseIcon = "";
if (_objectType isKindOf "CAManBase") then {
_baseDisplayName = localize LSTRING(SelfActionsRoot);
_baseIcon = "\a3\ui_f\data\IGUI\Cfg\Actions\eject_ca.paa";
@ -107,12 +102,9 @@ if (_objectType isKindOf "CAManBase") then {
};
};
// If the classname inherits from CAManBase, just copy it's menu without recompiling a new one
_actions = if (_isMan) then {
+ (missionNamespace getVariable QGVAR(SelfAct_CAManBase))
} else {
// Create a master action to base on self action
[
TRACE_1("Building ACE_SelfActions",_objectType);
// Create a master action to base on self action
private _actions = [
[
[
"ACE_SelfActions",
@ -127,11 +119,10 @@ _actions = if (_isMan) then {
{},
"Spine3",
10,
[false,true,false]
[false,true,false,false,false]
],
[_actionsCfg] call _recurseFnc
]
]
};
];
missionNamespace setVariable [_actionsVarName, _actions];

View File

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

View File

@ -13,7 +13,7 @@
* 6: Action parameters <ANY> (Optional)
* 7: Position (Position array, Position code or Selection Name) <ARRAY>, <CODE> or <STRING> (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)
*
* Return value:
@ -26,6 +26,8 @@
*/
#include "script_component.hpp"
// IGNORE_PRIVATE_WARNING(_actionName,_displayName,_icon,_statement,_condition,_insertChildren,_customParams,_position,_distance,_params,_modifierFunction);
params [
"_actionName",
"_displayName",
@ -41,16 +43,16 @@ params [
];
_position = if (_position isEqualType "") then {
// If the action is set to a selection, create the suitable code
compile format ["_target selectionPosition '%1'", _position];
// If the action is set to a selection, create the suitable code - IGNORE_PRIVATE_WARNING(_target);
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 {
if (_position isEqualType []) then {
// If the action is set to a array position, create the suitable code
compile format ["%1", _position];
} else {
_position;
};
_position;
};
};
[
_actionName,
@ -58,7 +60,6 @@ _position = if (_position isEqualType "") then {
_icon,
_statement,
_condition,
_insertChildren,
_customParams,
_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"
params ["_ctrl", "_index", "_text"];
//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];
_ctrl ctrlSetStructuredText parseText _text;
};

View File

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

View File

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

View File

@ -9,18 +9,20 @@
* Return value:
* Bool
*
* Example:
* [[["ACE_SelfActions", player],["ace_Gestures", player]], [["ACE_SelfActions", player]]] call ace_interact_menu_fnc_isSubPath
*
* Public: No
*/
#include "script_component.hpp"
params ["_longPath", "_shortPath"];
private ["_isSubPath","_i"];
_isSubPath = true;
private _isSubPath = true;
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 {
_isSubPath = false;
};

View File

@ -65,7 +65,7 @@ if (GVAR(useCursorMenu)) then {
// uiNamespace getVariable QGVAR(cursorMenuOpened);
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 ctrlCommit 0;
@ -75,8 +75,7 @@ if (GVAR(useCursorMenu)) then {
setMousePosition [0.5, 0.5];
};
GVAR(selfMenuOffset) = ((positionCameraToWorld [0, 0, 2]) call EFUNC(common,positionToASL)) vectorDiff
((positionCameraToWorld [0, 0, 0]) call EFUNC(common,positionToASL));
GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff (AGLtoASL (positionCameraToWorld [0, 0, 0]));
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)

View File

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

View File

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

View File

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

View File

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

View File

@ -15,21 +15,20 @@
*/
#include "script_component.hpp"
#define DEFAULT_ICON QUOTE(\z\ace\addons\interaction\ui\dot_ca.paa)
private ["_ctrl", "_pos", "_displayNum"];
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 {
_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)]);
if (GVAR(useCursorMenu)) then {
((finddisplay _displayNum) displayctrl (54021+GVAR(iconCount))) ctrlAddEventHandler ["MouseMoving", DFUNC(handleMouseMovement)];
((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 {
_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];
};
//_ctrl ctrlSetStructuredText parseText _text;
[_ctrl, GVAR(iconCount), _text] call FUNC(ctrlSetParsedTextCached);
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]
} else {
[(_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"
private ["_menuInSelectedPath", "_path", "_menuDepth", "_x", "_offset", "_newPos", "_forEachIndex", "_player", "_pos", "_target", "_textSettings"];
params ["_parentPath", "_action", "_sPos", "_angles"];
_action params ["_actionData", "_activeChildren", "_actionObject"];
_angles params ["_centerAngle", "_maxAngleSpan"];
_menuDepth = (count GVAR(menuDepthPath));
private _menuDepth = (count GVAR(menuDepthPath));
//BEGIN_COUNTER(constructing_paths);
// Store path to action
_path = +_parentPath;
private _path = +_parentPath;
_path pushBack [_actionData select 0,_actionObject];
// Check if the menu is on the selected path
_menuInSelectedPath = true;
private _menuInSelectedPath = true;
{
if (_forEachIndex >= (count GVAR(menuDepthPath))) exitWith {
_menuInSelectedPath = false;
@ -44,7 +42,7 @@ _menuInSelectedPath = true;
//BEGIN_COUNTER(constructing_colors);
//Get text color settings string
_textSettings = GVAR(colorSelectedSettings);
private _textSettings = GVAR(colorSelectedSettings);
if(!_menuInSelectedPath) then {
_textSettings = (GVAR(textSettingsMatrix) select (count _path)) select _menuDepth;
};
@ -68,13 +66,12 @@ if !(_menuInSelectedPath) exitWith {true};
//BEGIN_COUNTER(children);
private ["_numChildren","_angleSpan","_angle","_angleInterval","_scaleX", "_scaleY", "_offset", "_textSize"];
_numChildren = count _activeChildren;
_angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1));
private _numChildren = count _activeChildren;
private _angleSpan = _maxAngleSpan min (55 * ((_numChildren) - 1));
if (_angleSpan >= 305) then {
_angleSpan = 360;
};
_angleInterval = 55;
private _angleInterval = 55;
if (_angleSpan < 360) then {
if (_numChildren > 1) then {
_angleInterval = _angleSpan / (_numChildren - 1);
@ -87,15 +84,15 @@ if (_numChildren == 1) then {
};
// Scale menu based on the amount of children
_scaleX = 1;
_scaleY = 1;
private _scaleX = 1;
private _scaleY = 1;
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;
_scaleY = 0.17 * 0.30 * 4/3;
} 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);
_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));
};
_target = _actionObject;
_player = ACE_player;
private _target = _actionObject;
private _player = ACE_player;
//END_COUNTER(children);
_angle = _centerAngle - _angleSpan / 2;
private _angle = _centerAngle - _angleSpan / 2;
{
//BEGIN_COUNTER(children);
private ["_offset","_newPos"];
_newPos = if (GVAR(UseListMenu)) then {
private _newPos = if (GVAR(UseListMenu)) then {
[(_sPos select 0) + _scaleX,
(_sPos select 1) + _scaleY * (_forEachIndex - _numChildren/2 + 0.5)];
} else {
@ -122,8 +117,6 @@ _angle = _centerAngle - _angleSpan / 2;
(_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);
_angle = _angle + _angleInterval;

View File

@ -15,10 +15,8 @@
params ["_sPos", "_icon"];
private ["_displayNum", "_ctrl", "_pos"];
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)]);
if (GVAR(useCursorMenu)) then {
((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);
[(_sPos select 0)-(0.014*SafeZoneW), (_sPos select 1)-(0.014*SafeZoneW), 0.05*SafeZoneW, 0.035*SafeZoneW]
} else {

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/*
* Author: PabstMirror
* 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:
* 0: Interact Menu Type (0 - world, 1 - self) <NUMBER>
@ -10,9 +10,9 @@
* Nothing
*
* Example:
* [0] call ace_interact_menu_fnc_addHouseActions
* [0] call ace_interact_menu_fnc_userActions_addHouseActions
*
* Public: Yes
* Public: No
*/
#include "script_component.hpp"
@ -26,7 +26,6 @@ if (_interactionType != 0) exitWith {};
if ((vehicle ACE_player) != ACE_player) exitWith {};
[{
private ["_nearBuidlings", "_typeOfHouse", "_houseBeingScaned", "_actionSet", "_memPoints", "_memPointsActions", "_helperPos", "_helperObject"];
params ["_args", "_pfID"];
_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 (((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 {
_housesScaned pushBack _x;
} else {
_housesToScanForActions pushBack _x;
};
} forEach (_nearBuidlings - _housesScaned);
nil
} count (_nearBuidlings - _housesScaned);
_args set [0, (getPosASL ace_player)];
} else {
_houseBeingScaned = _housesToScanForActions deleteAt 0;
_typeOfHouse = typeOf _houseBeingScaned;
private _typeOfHouse = typeOf _houseBeingScaned;
//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)
if ((_houseBeingScaned != cursorTarget) && {((ACE_player distance _houseBeingScaned) - ((sizeOf _typeOfHouse) / 2)) > 4}) exitWith {};
_housesScaned pushBack _houseBeingScaned;
_actionSet = [_typeOfHouse] call FUNC(userActions_getHouseActions);
private _actionSet = [_typeOfHouse] call FUNC(userActions_getHouseActions);
_actionSet params ["_memPoints", "_memPointsActions"];
// systemChat format ["Add Actions for [%1] (count %2) @ %3", _typeOfHouse, (count _memPoints), diag_tickTime];
{
_helperPos = (_houseBeingScaned modelToWorld (_houseBeingScaned selectionPosition _x)) call EFUNC(common,positionToASL);
_helperObject = "ACE_LogicDummy" createVehicleLocal _helperPos;
private _helperPos = AGLtoASL (_houseBeingScaned modelToWorld (_houseBeingScaned selectionPosition _x));
private _helperObject = "ACE_LogicDummy" createVehicleLocal _helperPos;
_addedHelpers pushBack _helperObject;
_helperObject setVariable [QGVAR(building), _houseBeingScaned];
_helperObject setPosASL _helperPos;
@ -88,7 +88,8 @@ if ((vehicle ACE_player) != ACE_player) exitWith {};
{
[_helperObject, 0, [], _x] call EFUNC(interact_menu,addActionToObject);
} forEach (_memPointsActions select _forEachIndex);
nil
} count (_memPointsActions select _forEachIndex);
} forEach _memPoints;
};

View File

@ -8,22 +8,23 @@
* Return Value:
* [[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"
params ["_typeOfBuilding"];
private["_action", "_actionDisplayName", "_actionDisplayNameDefault", "_actionMaxDistance", "_actionOffset", "_actionPath", "_actionPosition", "_building", "_configPath", "_endIndex", "_iconImage", "_index", "_ladders", "_memPointIndex", "_memPoints", "_memPointsActions", "_startIndex"];
_searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding;
private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding;
if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex};
_memPoints = [];
_memPointsActions = [];
private _memPoints = [];
private _memPointsActions = [];
//Get the offset for a memory point:
_fnc_getMemPointOffset = {
private _fnc_getMemPointOffset = {
params ["_memoryPoint"];
_memPointIndex = _memPoints find _memoryPoint;
_actionOffset = [0,0,0];
@ -37,13 +38,13 @@ _fnc_getMemPointOffset = {
};
// Add UserActions for the building:
_fnc_userAction_Statement = {
private _fnc_userAction_Statement = {
params ["_target", "_player", "_variable"];
_variable params ["_actionStatement", "_actionCondition"];
this = _target getVariable [QGVAR(building), objNull];
call _actionStatement;
};
_fnc_userAction_Condition = {
private _fnc_userAction_Condition = {
params ["_target", "_player", "_variable"];
_variable params ["_actionStatement", "_actionCondition"];
this = _target getVariable [QGVAR(building), objNull];
@ -51,16 +52,16 @@ _fnc_userAction_Condition = {
call _actionCondition;
};
_configPath = configFile >> "CfgVehicles" >> _typeOfBuilding >> "UserActions";
private _configPath = configFile >> "CfgVehicles" >> _typeOfBuilding >> "UserActions";
for "_index" from 0 to ((count _configPath) - 1) do {
_actionPath = _configPath select _index;
private _actionPath = _configPath select _index;
_actionDisplayName = getText (_actionPath >> "displayName");
_actionDisplayNameDefault = getText (_actionPath >> "displayNameDefault");
_actionPosition = getText (_actionPath >> "position");
_actionCondition = getText (_actionPath >> "condition");
_actionStatement = getText (_actionPath >> "statement");
_actionMaxDistance = getNumber (_actionPath >> "radius");
private _actionDisplayName = getText (_actionPath >> "displayName");
private _actionDisplayNameDefault = getText (_actionPath >> "displayNameDefault");
private _actionPosition = getText (_actionPath >> "position");
private _actionCondition = getText (_actionPath >> "condition");
private _actionStatement = getText (_actionPath >> "statement");
private _actionMaxDistance = getNumber (_actionPath >> "radius");
if (_actionDisplayName == "") then {_actionDisplayName = (configName _x);};
if (_actionPosition == "") then {ERROR("Bad Position");};
@ -70,53 +71,52 @@ for "_index" from 0 to ((count _configPath) - 1) do {
_actionStatement = compile _actionStatement;
_actionCondition = compile _actionCondition;
_actionMaxDistance = _actionMaxDistance + 0.1; //increase range slightly
_iconImage = "";
//extension ~4x as fast:
_iconImage = "ace_parse_imagepath" callExtension _actionDisplayNameDefault;
private _iconImage = "ace_parse_imagepath" callExtension _actionDisplayNameDefault;
_actionOffset = [_actionPosition] call _fnc_getMemPointOffset;
_memPointIndex = _memPoints find _actionPosition;
private _actionOffset = [_actionPosition] call _fnc_getMemPointOffset;
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);
(_memPointsActions select _memPointIndex) pushBack _action;
};
// Add Ladder Actions for the building:
_fnc_ladder_ladderUp = {
private _fnc_ladder_ladderUp = {
params ["_target", "_player", "_variable"];
_variable params ["_ladderIndex"];
_building = _target getVariable [QGVAR(building), objNull];
private _building = _target getVariable [QGVAR(building), objNull];
TRACE_3("Ladder Action - UP",_player,_building,_ladderIndex);
_player action ["LadderUp", _building, _ladderIndex, 0];
};
_fnc_ladder_ladderDown = {
private _fnc_ladder_ladderDown = {
params ["_target", "_player", "_variable"];
_variable params ["_ladderIndex"];
_building = _target getVariable [QGVAR(building), objNull];
private _building = _target getVariable [QGVAR(building), objNull];
TRACE_3("Ladder Action - Down",_player,_building,_ladderIndex);
_player action ["LadderDown", _building, _ladderIndex, 1];
};
_fnc_ladder_conditional = {
private _fnc_ladder_conditional = {
params ["_target", "_player"];
//(Check distance < 2) and (Don't show actions if on a ladder)
((_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"];
_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";
_iconImage = "\A3\ui_f\data\igui\cfg\actions\ladderup_ca.paa";
private _actionDisplayName = localize "str_action_ladderup";
private _iconImage = "\A3\ui_f\data\igui\cfg\actions\ladderup_ca.paa";
//Ladder Up Action:
_actionOffset = [_ladderBottomMemPoint] call _fnc_getMemPointOffset;
private _actionOffset = [_ladderBottomMemPoint] call _fnc_getMemPointOffset;
_actionOffset = _actionOffset vectorAdd [0,0,1];
_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 _memPointIndex = _memPoints find _ladderBottomMemPoint;
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;
_actionDisplayName = localize "str_action_ladderdown";

View File

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