mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Arsenal - Add arsenal actions addition and removal via functions (#9318)
* Add and remove arsenal actions via functions * Fixed header * Update addons/arsenal/functions/fnc_addAction.sqf Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> * Update fnc_addSort.sqf * Update addons/arsenal/functions/fnc_removeAction.sqf Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> * Update addons/arsenal/functions/fnc_removeAction.sqf Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --------- Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com>
This commit is contained in:
parent
d290ca3d63
commit
a168330550
@ -1,3 +1,4 @@
|
||||
PREP(addAction);
|
||||
PREP(addDefaultLoadout);
|
||||
PREP(addListBoxItem);
|
||||
PREP(addRightPanelButton);
|
||||
@ -62,6 +63,7 @@ PREP(open3DEN);
|
||||
PREP(openBox);
|
||||
PREP(portVALoadouts);
|
||||
PREP(refresh);
|
||||
PREP(removeAction);
|
||||
PREP(removeBox);
|
||||
PREP(removeDefaultLoadout);
|
||||
PREP(removeSort);
|
||||
|
122
addons/arsenal/functions/fnc_addAction.sqf
Normal file
122
addons/arsenal/functions/fnc_addAction.sqf
Normal file
@ -0,0 +1,122 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Adds custom action buttons.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Tabs to add action to <ARRAY>
|
||||
* 1: Action class (unique string for each action) <STRING>
|
||||
* 2: Title <STRING>
|
||||
* 3: Actions <ARRAY of ARRAYS>
|
||||
* 4: Condition <CODE> (default: {true})
|
||||
* 5: Scope editor <NUMBER> (default: 2)
|
||||
*
|
||||
* Return Value:
|
||||
* 0: Array of IDs <ARRAY of STRINGS>
|
||||
*
|
||||
* Example:
|
||||
* [[0, 5], "TAG_myActions", "My Actions", [
|
||||
* ["text", "Text", {true}, "Text"],
|
||||
* ["statement", "Statement", {true}, "", {[_this select 0] call tag_fnc_myTextStatement}],
|
||||
* ["button", "Button", {true}, "", {}, {_this call tag_fnc_myAction}]
|
||||
* ]] call ace_arsenal_fnc_addAction
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [
|
||||
["_tabs", [], [[]]],
|
||||
["_rootClass", "", [""]],
|
||||
["_title", "", [""]],
|
||||
["_actions", [], [[]]],
|
||||
["_rootCondition", {true}, [{}]],
|
||||
["_scopeEditor", 2, [0]]
|
||||
];
|
||||
|
||||
// Compile actions from config (in case this is called before preInit)
|
||||
call FUNC(compileActions);
|
||||
|
||||
// Skip if not allowed in editor and in editor
|
||||
if (is3DEN && {_scopeEditor != 2}) exitWith {
|
||||
TRACE_1("Skipping action because in editor", _rootClass);
|
||||
[]
|
||||
};
|
||||
|
||||
// Class can't contain ~, because it's used for formatting result
|
||||
if ("~" in _rootClass) exitWith {
|
||||
TRACE_1("Classname can't contain '~'", _rootClass);
|
||||
[]
|
||||
};
|
||||
|
||||
private _return = [];
|
||||
|
||||
private _fnc_addToGroup = {
|
||||
params ["_group", "_tab"];
|
||||
|
||||
private _type = -1;
|
||||
|
||||
{
|
||||
_x params [["_class", "", [""]], ["_label", "", [""]], ["_condition", {true}, [{}]], ["_text", "", [""]], ["_textStatement", {}, [{}]], ["_statement", {}, [{}]]];
|
||||
|
||||
// Class can't contain ~, because it's used for formatting result
|
||||
if (_class == "" || {"~" in _class}) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Don't allow two of the same class
|
||||
if (_group findIf {(_x select 0) == _class} != -1) then {
|
||||
TRACE_1("An action with this ID already exists", _class);
|
||||
continue;
|
||||
};
|
||||
|
||||
_type = switch (false) do {
|
||||
case (_text == ""): {
|
||||
_statement = format ["{""%1""}", _text];
|
||||
ACTION_TYPE_TEXT
|
||||
};
|
||||
case (_textStatement isEqualTo {}): {
|
||||
_statement = _textStatement;
|
||||
ACTION_TYPE_TEXT
|
||||
};
|
||||
case (_statement isEqualTo {}): {
|
||||
_statement = _statement;
|
||||
ACTION_TYPE_BUTTON
|
||||
};
|
||||
default {
|
||||
-1
|
||||
};
|
||||
};
|
||||
|
||||
if (_type == -1) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
_statement = compile format [QUOTE([GVAR(center)] call %1), _statement];
|
||||
|
||||
_group pushBack [_class, _type, _label, _statement, _condition];
|
||||
_return pushBack ([_rootClass, _class, _tab] joinString "~");
|
||||
} forEach _actions;
|
||||
};
|
||||
|
||||
private _tab = [];
|
||||
private _index = -1;
|
||||
private _group = [];
|
||||
|
||||
{
|
||||
_tab = GVAR(actionList) select _x;
|
||||
_index = _tab findIf {(_x select 0) == _rootClass};
|
||||
|
||||
// Add to existing group
|
||||
if (_index != -1) then {
|
||||
[_tab select _index select 3, _x] call _fnc_addToGroup;
|
||||
} else {
|
||||
// Add to new group
|
||||
_group = [];
|
||||
|
||||
[_group, _x] call _fnc_addToGroup;
|
||||
|
||||
_tab pushBack [_rootClass, _title, _rootCondition, _group];
|
||||
};
|
||||
} forEach _tabs;
|
||||
|
||||
_return
|
@ -7,10 +7,10 @@
|
||||
* 0: Tabs to add sort to <ARRAY>
|
||||
* - 0: Left Tab Indexes <ARRAY of NUMBERS>
|
||||
* - 1: Right Tab Indexes <ARRAY of NUMBERS>
|
||||
* 1: Sort Class (a unique string for each algorithm) <STRING>
|
||||
* 1: Sort class (a unique string for each algorithm) <STRING>
|
||||
* 2: Title <STRING>
|
||||
* 3: Algorithm <CODE>
|
||||
* 4: Condition <CODE> (default: true)
|
||||
* 4: Condition <CODE> (default: {true})
|
||||
*
|
||||
* Return Value:
|
||||
* 0: Array of IDs <ARRAY of STRINGS>
|
||||
@ -27,7 +27,7 @@
|
||||
*
|
||||
* _fireRate sort true;
|
||||
* _fireRate param [0, 0]
|
||||
* }] call ace_arsenal_fnc_addSort;
|
||||
* }] call ace_arsenal_fnc_addSort
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
@ -37,8 +37,7 @@ params [
|
||||
["_class", "", [""]],
|
||||
["_title", "", [""]],
|
||||
["_statement", {}, [{}]],
|
||||
["_condition", {true}, [{}]],
|
||||
["_overwrite", false, [false]]
|
||||
["_condition", {true}, [{}]]
|
||||
];
|
||||
|
||||
_tabs params [
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Arsenal display <DISPLAY>
|
||||
* 1. Actions control <CONTROL>
|
||||
* 1: Actions control <CONTROL>
|
||||
* 2: Previous or next <BOOL> (false = previous, true = next)
|
||||
*
|
||||
* Return Value:
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brett Mayson
|
||||
* Create the internal actions arrays when needed for the first time
|
||||
* Create the internal actions arrays when needed for the first time.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
@ -39,10 +39,12 @@ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)
|
||||
|
||||
{
|
||||
private _scopeEditor = getNumber (_x >> "scopeEditor");
|
||||
|
||||
if (is3DEN && {_scopeEditor != 2}) then {continue};
|
||||
|
||||
private _configActions = "true" configClasses _x;
|
||||
|
||||
private _rootClass = configName _x;
|
||||
private _rootDisplayName = getText (_x >> "displayName");
|
||||
private _rootCondition = getText (_x >> "condition");
|
||||
private _rootTabs = getArray (_x >> "tabs");
|
||||
@ -56,6 +58,7 @@ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)
|
||||
private _group = [];
|
||||
|
||||
{
|
||||
private _class = configName _x;
|
||||
private _label = getText (_x >> "label");
|
||||
private _condition = getText (_x >> "condition");
|
||||
private _statement = getText (_x >> "statement");
|
||||
@ -79,9 +82,11 @@ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)
|
||||
-1
|
||||
};
|
||||
};
|
||||
|
||||
if (_type == -1) then {
|
||||
continue;
|
||||
};
|
||||
|
||||
_statement = compile format [QUOTE([GVAR(center)] call {%1}), _statement];
|
||||
|
||||
if (_condition != "") then {
|
||||
@ -90,12 +95,13 @@ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)
|
||||
_condition = {true};
|
||||
};
|
||||
|
||||
_group pushBack [_type, _label, _statement, _condition];
|
||||
// No duplicates are possible here
|
||||
_group pushBack [_class, _type, _label, _statement, _condition];
|
||||
} forEach _configActions;
|
||||
|
||||
{
|
||||
(_actionList select _x) pushBack [_rootDisplayName, _rootCondition, _group];
|
||||
(_actionList select _x) pushBack [_rootClass, _rootDisplayName, _rootCondition, _group];
|
||||
} forEach _rootTabs;
|
||||
} forEach _configGroupEntries;
|
||||
|
||||
missionNamespace setVariable [QGVAR(actionList), _actionList];
|
||||
GVAR(actionList) = _actionList;
|
||||
|
@ -63,7 +63,6 @@ private _sortListRightPanel = [
|
||||
[] // Misc 7
|
||||
];
|
||||
|
||||
//------------------------- Config handling
|
||||
private _class = "";
|
||||
private _displayName = "";
|
||||
private _statement = "";
|
||||
|
@ -78,7 +78,6 @@ private _statsListRightPanel = [
|
||||
[] // Misc 7
|
||||
];
|
||||
|
||||
//------------------------- Config handling
|
||||
private _finalArray = [];
|
||||
private _class = "";
|
||||
private _stats = [];
|
||||
@ -127,6 +126,5 @@ private _priority = 0;
|
||||
[_statsListLeftPanel] call _fnc_sortLists;
|
||||
[_statsListRightPanel] call _fnc_sortLists;
|
||||
|
||||
//------------------------- Config Handling
|
||||
GVAR(statsListLeftPanel) = _statsListLeftPanel;
|
||||
GVAR(statsListRightPanel) = _statsListRightPanel;
|
||||
|
@ -42,7 +42,7 @@ private _panel = [
|
||||
] find GVAR(currentLeftPanel);
|
||||
|
||||
private _groups = (GVAR(actionList) select _panel) select {
|
||||
[GVAR(center)] call (_x select 1)
|
||||
[GVAR(center)] call (_x select 2)
|
||||
};
|
||||
|
||||
private _show = _groups isNotEqualTo [];
|
||||
@ -57,9 +57,11 @@ private _actionsCurrentPageCtrl = _display displayCtrl IDC_actionsCurrentPage;
|
||||
|
||||
private _currentPage = GVAR(currentActionPage);
|
||||
private _pages = count _groups;
|
||||
|
||||
if (_currentPage < 0) then {
|
||||
_currentPage = _pages - 1;
|
||||
};
|
||||
|
||||
if (_currentPage >= _pages) then {
|
||||
_currentPage = 0;
|
||||
GVAR(currentActionPage) = _currentPage;
|
||||
@ -72,25 +74,28 @@ if (_currentPage >= _pages) then {
|
||||
} forEach [IDC_actionsPreviousPage, IDC_actionsNextPage];
|
||||
|
||||
private _group = _groups select _currentPage;
|
||||
private _items = _group select 2 select {
|
||||
[GVAR(center)] call (_x select 3)
|
||||
private _items = _group select 3 select {
|
||||
[GVAR(center)] call (_x select 4)
|
||||
};
|
||||
|
||||
_actionsCurrentPageCtrl ctrlSetText (_group select 0);
|
||||
_actionsCurrentPageCtrl ctrlSetText (_group select 1);
|
||||
_actionsCurrentPageCtrl ctrlSetFade 0;
|
||||
_actionsCurrentPageCtrl ctrlShow true;
|
||||
_actionsCurrentPageCtrl ctrlCommit 0;
|
||||
|
||||
{
|
||||
_x params ["_type", "_label", "_statement"];
|
||||
_x params ["", "_type", "_label", "_statement"];
|
||||
|
||||
private _idc = 9001 + _forEachIndex * 2;
|
||||
private _actionTextCtrl = _display displayCtrl _idc;
|
||||
private _actionButtonCtrl = _display displayCtrl (_idc + 1);
|
||||
|
||||
switch (_type) do {
|
||||
case ACTION_TYPE_BUTTON: {
|
||||
_actionButtonCtrl ctrlRemoveAllEventHandlers "ButtonClick";
|
||||
_actionButtonCtrl ctrlAddEventHandler ["ButtonClick", {
|
||||
if (is3DEN) exitWith {call FUNC(refresh)};
|
||||
|
||||
[{
|
||||
call FUNC(refresh);
|
||||
}] call CBA_fnc_execNextFrame;
|
||||
@ -104,10 +109,12 @@ _actionsCurrentPageCtrl ctrlCommit 0;
|
||||
_actionTextCtrl ctrlCommit 0;
|
||||
};
|
||||
case ACTION_TYPE_TEXT: {
|
||||
private _text = (call _statement);
|
||||
private _text = call _statement;
|
||||
|
||||
if (isNil "_text") then {
|
||||
_text = "";
|
||||
};
|
||||
|
||||
_actionTextCtrl ctrlSetText _text;
|
||||
_actionTextCtrl ctrlSetFade 0;
|
||||
_actionTextCtrl ctrlCommit 0;
|
||||
@ -129,6 +136,7 @@ private _actionCount = count _items;
|
||||
private _idc = 9001 + _x * 2;
|
||||
private _actionTextCtrl = _display displayCtrl _idc;
|
||||
private _actionButtonCtrl = _display displayCtrl (_idc + 1);
|
||||
|
||||
_actionTextCtrl ctrlSetFade 1;
|
||||
_actionTextCtrl ctrlCommit 0;
|
||||
_actionButtonCtrl ctrlSetFade 1;
|
||||
|
41
addons/arsenal/functions/fnc_removeAction.sqf
Normal file
41
addons/arsenal/functions/fnc_removeAction.sqf
Normal file
@ -0,0 +1,41 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Remove a custom action button from ACE Arsenal.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Array of IDs <ARRAY of STRINGS>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [["TAG_myActions~text~0", "TAG_myActions~statement~0", "TAG_myActions~button~0"]] call ace_arsenal_fnc_removeAction
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params ["_IDList"];
|
||||
|
||||
// Compile sorts from config (in case this is called before preInit)
|
||||
call FUNC(compileActions);
|
||||
|
||||
// Remove entries (all names are unique, there are no duplicates)
|
||||
{
|
||||
(_x splitString "~") params ["_rootClass", "_class", "_tab"];
|
||||
|
||||
_tab = parseNumber _tab;
|
||||
|
||||
{
|
||||
if ((_x select 0) == _rootClass) exitWith {
|
||||
(_x select 3) deleteAt ((_x select 3) findIf {(_x select 0) == _class});
|
||||
|
||||
// If no entries left in group, remove group
|
||||
if ((_x select 3) isEqualTo []) then {
|
||||
(GVAR(actionList) select _tab) deleteAt _forEachIndex;
|
||||
};
|
||||
};
|
||||
} forEach (GVAR(actionList) select _tab);
|
||||
} forEach _IDList;
|
||||
|
||||
nil // return
|
@ -4,20 +4,20 @@ class EGVAR(arsenal,actions) {
|
||||
condition = QUOTE(_this call FUNC(hasGunbag));
|
||||
scopeEditor = 0; // variables are reset between 3DEN and mission start
|
||||
tabs[] = {0,5};
|
||||
class status {
|
||||
class GVAR(status) {
|
||||
textStatement = QUOTE([_this select 0] call FUNC(weaponName));
|
||||
};
|
||||
class store {
|
||||
class GVAR(store) {
|
||||
label = CSTRING(ToGunbag);
|
||||
condition = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(canInteract) == 0);
|
||||
statement = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(toGunbagCallback));
|
||||
};
|
||||
class retrieve {
|
||||
class GVAR(retrieve) {
|
||||
label = CSTRING(OffGunbag);
|
||||
condition = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(canInteract) == 1);
|
||||
statement = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(offGunbagCallback));
|
||||
};
|
||||
class swap {
|
||||
class GVAR(swap) {
|
||||
label = CSTRING(SwapGunbag);
|
||||
condition = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(canInteract) == 2);
|
||||
statement = QUOTE([ARR_2(_this select 0,_this select 0)] call FUNC(swapGunbagCallback));
|
||||
|
@ -256,6 +256,8 @@ Example:
|
||||
}, {true}]] call ace_arsenal_fnc_addStat;
|
||||
```
|
||||
|
||||
If a stat already exists (so same class ID and tab), it will ignore the new addition.
|
||||
|
||||
### 5.3 Removing stats via a function
|
||||
|
||||
`ace_arsenal_fnc_removeStat`
|
||||
@ -350,7 +352,7 @@ The argument passed to the condition is:
|
||||
1 | Stat class ID | String | Required
|
||||
2 | Title | String | Required
|
||||
3 | Algorithm | Code | Required
|
||||
4 | Condition | Code | Optional (default: `true`)
|
||||
4 | Condition | Code | Optional (default: `{true}`)
|
||||
|
||||
Return Value:
|
||||
- Array of sort IDs
|
||||
@ -373,6 +375,8 @@ Example:
|
||||
|
||||
Sorting method IDs are unique and are generated in the same fashion as the stat IDs (see `5.3 Removing stats via a function`).
|
||||
|
||||
If a sorting method already exists (so same class ID and tab), it will ignore the new addition.
|
||||
|
||||
### 6.3 Removing sorting methods via a function
|
||||
|
||||
`ace_arsenal_fnc_removeSort`
|
||||
@ -395,8 +399,6 @@ ACE Arsenal actions are customizable, this will show you how.
|
||||
|
||||
### 7.1 Adding actions via config
|
||||
|
||||
Actions use the same tab definitions as stats, found above.
|
||||
|
||||
```cpp
|
||||
class ace_arsenal_actions {
|
||||
class TAG_myActions {
|
||||
@ -422,6 +424,57 @@ class ace_arsenal_actions {
|
||||
```
|
||||
The focused unit object is passed to the condition and statement functions.
|
||||
|
||||
### 7.2 Adding sorting methods via a function
|
||||
|
||||
`ace_arsenal_fnc_addAction`
|
||||
|
||||
| | Argument | Type | Optional (default value)
|
||||
--- | -------- | ---- | ------------------------
|
||||
0 | Tabs to add the sort to | Array of numbers | Required
|
||||
1 | Action class ID | String | Required
|
||||
2 | Title | String | Required
|
||||
3 | Actions | Array of arrays | Required
|
||||
4 | Condition | Code | Optional (default: `{true}`)
|
||||
5 | Scope editor | Number | Optional (default: `2`)
|
||||
|
||||
Return Value:
|
||||
- Array of action IDs
|
||||
|
||||
Example:
|
||||
```sqf
|
||||
[[0, 5], "TAG_myActions", "My Actions", [
|
||||
["text", "Text", {true}, "Text"],
|
||||
["statement", "Statement", {true}, "", {[_this select 0] call tag_fnc_myTextStatement}],
|
||||
["button", "Button", {true}, "", {}, {_this call tag_fnc_myAction}]
|
||||
]] call ace_arsenal_fnc_addAction;
|
||||
```
|
||||
|
||||
The example above results in the same actions as in `7.1 Adding actions via config`.
|
||||
|
||||
Action IDs are unique and are generated as a string in the following fashion:
|
||||
`_rootClassName + "~" + _class + "~" + _tab`
|
||||
|
||||
The example above returns:
|
||||
`["TAG_myActions~text~0","TAG_myActions~statement~0","TAG_myActions~button~0","TAG_myActions~text~5","TAG_myActions~statement~5","TAG_myActions~button~5"]`
|
||||
|
||||
If an action already exists (so same class ID and tab within an action), it will ignore the new addition.
|
||||
|
||||
### 7.3 Removing actions via a function
|
||||
|
||||
`ace_arsenal_fnc_removeAction`
|
||||
|
||||
| | Argument | Type | Optional (default value)
|
||||
---| -------- | ---- | ------------------------
|
||||
0 | Array of IDs | Array | Required
|
||||
|
||||
Action IDs are unique and their generation is explained in `7.2 Adding sorting methods via a function`.
|
||||
|
||||
For config added actions the classname is used, for function added ones the string provided is used.
|
||||
|
||||
### 7.4 Action tab numbers
|
||||
|
||||
The same numbers are used for actions as for stats (see `5.4 Stat tab numbers`).
|
||||
|
||||
## 8. Eventhandlers
|
||||
|
||||
All are local.
|
||||
|
Loading…
Reference in New Issue
Block a user