Add ACE Arsenal stats (#6110)

* Add test class

* Add stats mockup

* Merge branch 'master' of https://github.com/acemod/ACE3 into arsenalStats

* Finish mockup, add basic hide/show logic

* Add base for stats

* Use CBA EHs for stats to allow 3rd party mods of it

* Add handleStats and most of the UI behaviors for stats

* Continue work on stats

* Add container stats

* Add page support for stats

* Add text for the ROF stat

* Add accuracy in MOA for the accuracy stat

* Change accuracy shown number to 1 decimal instead of 2

* Add MIL in the dispersion stat text

* Change stats layout, remove dummy text strings

* Add some AB stats

* Remove last test string

* Replace configExtremes by normal lookup where it's relevant

* Add "undefined value" string when AB stat isn't present

Mostly for laucnhers

* Fix typo in preInit

* Change drag model stat to ballistic coef

* Fix issue with unused stats, change text to white when bar is present

* Rewrite some part of handleStats

Reason: add support for conditions, less redundant code, less reasons for dedmen to emasculate me

* Re-add _hideUnusedFnc, handle empty stats arrays

* Pass args to stat conditions, add test condition stat

* Add hearing related stats

* Remove the padding between stats and the stat bar / text

* Add strings for stats

* Change stats window to fit baer's suggestion

* Algin the close stats button, add missing strings

* Finish code review

* Add missing newline

* Remove duplicate strings

* Add explosive range stat

* Use proper string for the explo range stat

* Fix capitalization for ctrlParent

* Fix conditional stats blocking other stats

* Add better integration for ballistics, hearing and explosive stats

* Replace the private array in handleStat by params

* Add backblast stats

* Add backblast stat strings

* Add flashlight map color and g-force reduction stats

* Shorten preInit

* Change stats close button to fit arsenal design

* Improve stats page indicator look

* Rework how stats are stored and retrieved

* Remove args config entry, add priority entry, add vanilla weapon stats

* Add vanilla container stats

* Remove some lines in preInit

* Add ballistics stats

* Add hearing stats

* Remove uneeded config entries

* Add explosive range stat

* Add backblast stats

* Add spaces after semicolons in statements

To make JJ happy because I don't care.

* Add flashlights map color stat

* Add gforce reduction stat

FINALLY FUCKING DONE

* Fix headers for the new stats funcs

* Add add / remove stat API

* Fix typo in removeStat header

* Remove uneeded inline func

* Clean up add / remove stat

* Move all CfgACEArsenalStats entries to their own file

* Replace STR_ACE_Ballistics_statAmmo by a BI string

* Add script profiler related macro and code

* Use the highest ballistic coef instead of first one defined

* Add support for future ammo displayname

* Add ACE_standardAtmosphere for ballistic coef

* Add mag muzzle velocity stat

* Add weapon muzzle velocity stat

* Add comment explaining the ENABLE_PERF_PROFILING macro

* Change cfgACEArsenalStats to ACE_Arsenal_Stats

* Make JJ less pissy about spaces around =

* Fix indentation in weaponMuzzleVelocity, use param

* Use GVAR and EGVAR when appropriate

* Prefix all stats except the base class

* Fix Merge

* Fix aspect ratio scaling of stats panel

* Minor fixes
This commit is contained in:
Josuan Albin 2018-02-15 17:03:22 +01:00 committed by PabstMirror
parent f214b884a2
commit 1d6e07d18f
57 changed files with 1564 additions and 23 deletions

View File

@ -0,0 +1,96 @@
class GVAR(stats) {
class statBase {
scope = 1;
priority = 0;
stats[] = {};
displayName = "";
showBar = 0;
showText = 0;
barStatement = "";
textStatement = "";
condition = "true";
tabs[] = {{}, {}};
};
class ACE_bananaPotassium: statBase {
scope = 2;
displayName= CSTRING(statPotassium);
showBar = 1;
barStatement = "1";
condition = QUOTE((configName (_this select 1)) == 'ACE_Banana');
tabs[] = {{}, {7}};
};
class ACE_mass: statBase {
scope = 2;
displayName= "$STR_a3_rscdisplayarsenal_stat_weight";
showText = 1;
textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_mass));
tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}};
};
class ACE_rateOfFire: statBase {
scope = 2;
priority = 5;
stats[] = {"reloadTime"};
displayName= "$STR_a3_rscdisplayarsenal_stat_rof";
showBar = 1;
showText = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(-1.4, 0.31)], [ARR_2(1, 0.01)], true)])] call FUNC(statBarStatement_default));
textStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-1.4, 0.31)], false)])] call FUNC(statTextStatement_rateOfFire));
tabs[] = {{0,1}, {}};
};
class ACE_accuracy: statBase {
scope = 2;
priority = 4;
stats[] = {"dispersion"};
displayName = "$STR_a3_rscdisplayarsenal_stat_dispersion";
showBar = 1;
showText = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(-4, -1.7)], [ARR_2(1, 0.01)], true)])] call FUNC(statBarStatement_default));
textStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-4, -1.7)], false)])] call FUNC(statTextStatement_accuracy));
tabs[] = {{0,1}, {}};
};
class ACE_maxZeroing: statBase {
scope = 2;
priority = 3;
stats[] = {"maxZeroing"};
displayName = "$STR_a3_rscdisplayarsenal_stat_range";
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 2500)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default));
tabs[] = {{0,1,2}, {}};
};
class ACE_impact: statBase {
scope = 2;
priority = 2;
stats[] = {"hit", "initSpeed"};
displayName = "$STR_a3_rscdisplayarsenal_stat_impact";
showBar = 1;
barStatement = QUOTE([ARR_3(_this select 0, _this select 1, [ARR_3([ARR_2(0, 3.2)], [ARR_2(-1, 1100)], 2006)])] call FUNC(statBarStatement_impact));
tabs[] = {{0,1,2}, {}};
};
class ACE_ballisticProtection: statBase {
scope = 2;
priority = 5;
stats[] = {"passthrough"};
displayName = "$STR_a3_rscdisplayarsenal_stat_passthrough";
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 0.63)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default));
tabs[] = {{3,4,6}, {}};
};
class ACE_explosiveResistance: statBase {
scope = 2;
priority = 4;
stats[] = {"armor"};
displayName = "$STR_a3_rscdisplayarsenal_stat_armor";
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 0.80)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default));
tabs[] = {{3,4,6}, {}};
};
class ACE_load: statBase {
scope = 2;
priority = 3;
stats[] = {"maximumLoad"};
displayName = "$STR_a3_rscdisplayarsenal_stat_load";
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 500)], [ARR_2(0.01, 1)], false)])] call FUNC(statBarStatement_default));
tabs[] = {{3,4,5}, {}};
};
};

View File

@ -1,4 +1,5 @@
PREP(addListBoxItem); PREP(addListBoxItem);
PREP(addStat);
PREP(addVirtualItems); PREP(addVirtualItems);
PREP(buttonCargo); PREP(buttonCargo);
PREP(buttonClearAll); PREP(buttonClearAll);
@ -10,7 +11,10 @@ PREP(buttonLoadoutsLoad);
PREP(buttonLoadoutsRename); PREP(buttonLoadoutsRename);
PREP(buttonLoadoutsSave); PREP(buttonLoadoutsSave);
PREP(buttonLoadoutsShare); PREP(buttonLoadoutsShare);
PREP(buttonStats);
PREP(buttonStatsPage);
PREP(clearSearchbar); PREP(clearSearchbar);
PREP(compileStats);
PREP(fillLeftPanel); PREP(fillLeftPanel);
PREP(fillLoadoutsList); PREP(fillLoadoutsList);
PREP(fillRightPanel); PREP(fillRightPanel);
@ -18,6 +22,7 @@ PREP(handleLoadoutsSearchbar);
PREP(handleMouse); PREP(handleMouse);
PREP(handleScrollWheel); PREP(handleScrollWheel);
PREP(handleSearchbar); PREP(handleSearchbar);
PREP(handleStats);
PREP(initBox); PREP(initBox);
PREP(itemInfo); PREP(itemInfo);
PREP(loadoutsChangeTab); PREP(loadoutsChangeTab);
@ -37,10 +42,16 @@ PREP(open3DEN);
PREP(openBox); PREP(openBox);
PREP(portVALoadouts); PREP(portVALoadouts);
PREP(removeBox); PREP(removeBox);
PREP(removeStat);
PREP(removeVirtualItems); PREP(removeVirtualItems);
PREP(scanConfig); PREP(scanConfig);
PREP(showItem); PREP(showItem);
PREP(sortPanel); PREP(sortPanel);
PREP(statBarStatement_default);
PREP(statBarStatement_impact);
PREP(statTextStatement_accuracy);
PREP(statTextStatement_mass);
PREP(statTextStatement_rateOfFire);
PREP(updateCamPos); PREP(updateCamPos);
PREP(updateRightPanel); PREP(updateRightPanel);
PREP(updateUniqueItemsList); PREP(updateUniqueItemsList);

View File

@ -1,4 +1,5 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "defines.hpp"
ADDON = false; ADDON = false;
@ -20,4 +21,41 @@ GVAR(modList) = ["","curator","kart","heli","mark","expansion","expansionpremium
[QGVAR(allowSharedLoadouts), "CHECKBOX", localize LSTRING(allowSharingSetting), localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init; [QGVAR(allowSharedLoadouts), "CHECKBOX", localize LSTRING(allowSharingSetting), localize LSTRING(settingCategory), true, true] call CBA_Settings_fnc_init;
[QGVAR(EnableRPTLog), "CHECKBOX", [LSTRING(printToRPTSetting), LSTRING(printToRPTTooltip)], localize LSTRING(settingCategory), false, false] call CBA_Settings_fnc_init; [QGVAR(EnableRPTLog), "CHECKBOX", [LSTRING(printToRPTSetting), LSTRING(printToRPTTooltip)], localize LSTRING(settingCategory), false, false] call CBA_Settings_fnc_init;
[QGVAR(statsToggle), {
params ["_display", "_showStats"];
private _statsCtrlGroupCtrl = _display displayCtrl IDC_statsBox;
private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage;
private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage;
private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage;
private _statsButtonCtrl = _display displayCtrl IDC_statsButton;
private _statsButtonCloseCtrl = _display displayCtrl IDC_statsButtonClose;
{
_x ctrlShow (GVAR(showStats) && {_showStats});
} forEach [
_statsCtrlGroupCtrl,
_statsPreviousPageCtrl,
_statsNextPageCtrl,
_statsCurrentPageCtrl,
_statsButtonCloseCtrl
];
_statsButtonCtrl ctrlShow (!GVAR(showStats) && {_showStats})
}] call CBA_fnc_addEventHandler;
[QGVAR(statsButton), {
_this call FUNC(buttonStats);
}] call CBA_fnc_addEventHandler;
[QGVAR(statsChangePage), {
_this call FUNC(buttonStatsPage);
}] call CBA_fnc_addEventHandler;
[QGVAR(displayStats), {
_this call FUNC(handleStats);
}] call CBA_fnc_addEventHandler;
ADDON = true; ADDON = true;

View File

@ -3,3 +3,4 @@
#include "XEH_PREP.hpp" #include "XEH_PREP.hpp"
call FUNC(scanConfig); call FUNC(scanConfig);
call FUNC(compileStats);

View File

@ -39,3 +39,4 @@ class Cfg3DEN {
#include "ui\RscAttributes.hpp" #include "ui\RscAttributes.hpp"
#include "CfgEventHandlers.hpp" #include "CfgEventHandlers.hpp"
#include "RscDisplayMain.hpp" #include "RscDisplayMain.hpp"
#include "ACE_Arsenal_Stats.hpp"

View File

@ -104,6 +104,32 @@
#define IDC_buttonMisc 38 #define IDC_buttonMisc 38
#define IDC_buttonRemoveAllSelected 39 #define IDC_buttonRemoveAllSelected 39
#define IDC_buttonRemoveAll 40 #define IDC_buttonRemoveAll 40
#define IDC_statsBox 51
#define IDC_statsTitle1 5101
#define IDC_statsBackground1 5102
#define IDC_statsBar1 5103
#define IDC_statsText1 5104
#define IDC_statsTitle2 5105
#define IDC_statsBackground2 5106
#define IDC_statsBar2 5107
#define IDC_statsText2 5108
#define IDC_statsTitle3 5109
#define IDC_statsBackground3 5110
#define IDC_statsBar3 5111
#define IDC_statsText3 5112
#define IDC_statsTitle4 5113
#define IDC_statsBackground4 5114
#define IDC_statsBar4 5115
#define IDC_statsText4 5116
#define IDC_statsTitle5 5117
#define IDC_statsBackground5 5118
#define IDC_statsBar5 5119
#define IDC_statsText5 5120
#define IDC_statsPreviousPage 52
#define IDC_statsNextPage 53
#define IDC_statsCurrentPage 54
#define IDC_statsButton 55
#define IDC_statsButtonClose 56
#define IDD_loadouts_display 1127002 #define IDD_loadouts_display 1127002
#define IDC_centerBox 3 #define IDC_centerBox 3

View File

@ -0,0 +1,99 @@
/*
* Author: Alganthe
* Add a stat to ACE Arsenal.
*
* Arguments:
* 0: Tabs to add the stat to (ARRAY of ARRAYS)
* 0.1: Left tab indexes (ARRAY of NUMBERS)
* 0.2 Right tab indexes (ARRAY of NUMBERS)
* 1: Stat class (STRING) (A unique string for each stat)
* 2: Config entries to pass (ARRAY of STRINGS)
* 3: Title (STRING)
* 4: Show bar / show text bools (ARRAY of BOOLS)
* 4.1 Show bar (BOOL)
* 4.2 Show text (BOOL)
* 5: Array of statements (ARRAY of ARRAYS)
* 5.1: Bar code (CODE)
* 5.2 Text code (CODE)
* 5.3 Condition code (CODE)
* 6: Priority (NUMBER) (Optional)
*
* Return Value:
* 0: Array of IDs (ARRAY of STRINGS)
*
* Example:
* [[[0,1,2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, {
params ["_statsArray", "_itemCfg"];
getNumber (_itemCfg >> _statsArray select 0)
}, {true}]] call ACE_arsenal_fnc_addStat
*
* Public: Yes
*/
#include "script_component.hpp"
params [
["_tabs", [[], []], [[]], 2],
["_class", "", [""]],
["_stats", [], [[]]],
["_title", "", [""]],
["_bools", [false, false], [[]], 2],
["_statements", [{}, {}, {true}], [[]], 3],
["_priority", 0, [0]]
];
_tabs params [
["_leftTabs", [], [[]]],
["_rightTabs", [], [[]]]
];
_bools params [["_showBar", false, [false]], ["_showText", false, [false]]];
_statements params [
["_barStatement", {}, [{}]],
["_textStatement", {}, [{}]],
["_condition", {true}, [{}]]
];
private _statsListLeftPanel = uiNamespace getVariable QGVAR(statsListLeftPanel);
private _statsListRightPanel = uiNamespace getVariable QGVAR(statsListRightPanel);
private _returnArray = [];
private _fnc_addToTabs = {
params ["_tabsList", "_tabsToAddTo", "_sideString", "_returnIndex"];
{
private _currentTab = _tabsList select _x;
private _finalID = [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString "";
if ({{_x select 0 == _finalID} count _x > 0} count _currentTab > 0) then {
TRACE_1("A stat with this ID already exists", _finalID);
} else {
private _arrayToSave = +_finalArray;
_arrayToSave set [0, _finalID];
_returnArray pushBack _finalID;
// Add to existing page if there's enough space, otherwise create a new page
if ({count _x < 5} count _currentTab > 0) then {
{
if (count _x < 5) exitWith {
(_currentTab select _forEachIndex) append [_arrayToSave];
};
} foreach _currentTab;
} else {
_currentTab pushBack [_arrayToSave];
};
};
} foreach _tabsToAddTo;
};
private _finalArray = ["", _stats, _title, [_showBar, _showText], [_barStatement, _textStatement, _condition], _priority];
if (count _leftTabs > 0) then {
[_statsListLeftPanel, _leftTabs, "L", 0] call _fnc_addToTabs;
};
if (count _rightTabs > 0) then {
[_statsListRightPanel, _rightTabs, "R", 1] call _fnc_addToTabs;
};
_returnArray

View File

@ -48,5 +48,12 @@ private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar);
IDC_buttonCurrentMag, IDC_buttonCurrentMag,
IDC_buttonCurrentMag2, IDC_buttonCurrentMag2,
IDC_iconBackgroundCurrentMag, IDC_iconBackgroundCurrentMag,
IDC_iconBackgroundCurrentMag2 IDC_iconBackgroundCurrentMag2,
IDC_statsButton,
IDC_statsPreviousPage,
IDC_statsNextPage,
IDC_statsCurrentPage,
IDC_statsButtonClose
]; ];
[QGVAR(statsToggle), [_display, _showToggle]] call CBA_fnc_localEvent;

View File

@ -0,0 +1,31 @@
/*
* Author: Alganthe
* Toggle the stats control group
*
* Arguments:
* 0: Arsenal display <DISPLAY>
* 1: Button control <CONTROL>
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
#include "..\defines.hpp"
params ["_display"];
(_display displayCtrl IDC_statsButton) ctrlShow GVAR(showStats);
GVAR(showStats) = !GVAR(showStats);
{
(_display displayCtrl _x) ctrlShow GVAR(showStats);
} foreach [
IDC_statsBox,
IDC_statsPreviousPage,
IDC_statsNextPage,
IDC_statsCurrentPage,
IDC_statsButtonClose
];

View File

@ -0,0 +1,29 @@
/*
* Author: Alganthe
* Handles the previous / next page buttons for stats
*
* Arguments:
* 0: Arsenal display <DISPLAY>
* 1: Previous or next <BOOL> (false = previous, true = next)
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
#include "..\defines.hpp"
params ["_display", "_control", "_nextPage"];
TRACE_1("control enabled", ctrlEnabled _control);
if !(ctrlEnabled _control) exitWith {};
GVAR(statsInfo) params ["_isLeftPanel", "_statsIndex", "_panelControl", "_curSel", "_itemCfg"];
private _pageList = [GVAR(statsPagesRight), GVAR(statsPagesLeft)] select (_isLeftPanel);
private _newPageNumber = [(_pageList select _statsIndex) - 1, (_pageList select _statsIndex) + 1] select _nextPage;
_pageList set [_statsIndex, _newPageNumber];
[QGVAR(displayStats), [_display, _panelControl, _curSel, _itemCfg]] call CBA_fnc_localEvent;

View File

@ -0,0 +1,133 @@
/*
* Author: Alganthe
* Create the internal stats arrays on preStart
*
* Arguments:
* None
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
private _fnc_addToTabs = {
params ["_tabsList", "_tabsToAddTo", "_sideString"];
{
private _currentTab = _tabsList select _x;
private _availablePagesCount = {count _x < 5} count _currentTab;
private _arrayToSave = +_finalArray;
_arrayToSave set [0, ([_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString "")];
if (_availablePagesCount > 0) then {
{
if (count _x < 5) exitWith {
(_currentTab select _forEachIndex) append [_arrayToSave];
};
} foreach _currentTab;
} else {
_currentTab pushBack [_arrayToSave];
};
} foreach _tabsToAddTo;
};
private _fnc_sortLists = {
params ["_tabsList"];
{
private _page = _x;
{
{
reverse _x;
} foreach _x;
_x sort false;
{
reverse _x;
} foreach _x;
} foreach _page;
} foreach _tabsList;
};
private _statsListLeftPanel = uiNamespace getVariable [QGVAR(statsListLeftPanel), [
[[]], // Primary 0
[[]], // Handgun 1
[[]], // Launcher 2
[[]], // Uniform 3
[[]], // Vests 4
[[]], // Backpacks 5
[[]], // Headgear 6
[[]], // Goggles 7
[[]], // NVGs 8
[[]], // Binoculars 9
[[]], // Map 10
[[]], // GPS 11
[[]], // Radio 12
[[]], // Compass 13
[[]] // Watch 14
]];
private _statsListRightPanel = uiNamespace getVariable [QGVAR(statsListRightPanel), [
[[]], // Optics 0
[[]], // Side accs 1
[[]], // Muzzle 2
[[]], // Bipod 3
[[]], // Mag 4
[[]], // Throw 5
[[]], // Put 6
[[]] // Misc 7
]];
//------------------------- Config handling
private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> QGVAR(stats));
{
private _finalArray = [];
private _class = configName _x;
private _stats = getArray (_x >> "stats");
private _displayName = getText (_x >> "displayName");
private _showBar = getNumber (_x >> "showBar") == 1;
private _showText = getNumber (_x >> "showText") == 1;
private _condition = getText (_x >> "condition");
private _priority = getNumber (_x >> "priority");
(getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"];
if (_condition != "") then {
_condition = compile _condition;
};
_finalArray = ["", _stats, _displayName, [_showBar, _showText], [{}, {}, _condition], _priority];
if (_showBar) then {
private _barStatement = compile (getText (_x >> "barStatement"));
(_finalArray select 4) set [0, _barStatement];
};
if (_showText) then {
private _textStatement = compile (getText (_x >> "textStatement"));
(_finalArray select 4) set [1, _textStatement];
};
TRACE_3("stats array", _finalArray, _leftTabsList, _rightTabsList);
if (count _leftTabsList > 0) then {
[_statsListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs;
};
if (count _rightTabsList > 0) then {
[_statsListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs;
};
} foreach _configEntries;
[_statsListLeftPanel] call _fnc_sortLists;
[_statsListRightPanel] call _fnc_sortLists;
//------------------------- Config Handling
uiNamespace setVariable [QGVAR(statsListLeftPanel), _statsListLeftPanel];
uiNamespace setVariable [QGVAR(statsListRightPanel), _statsListRightPanel];

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeFillLeftPanel = createProfileScope QFUNC(fillLeftPanel);
#endif
params ["_display", "_control"]; params ["_display", "_control"];
private _ctrlIDC = ctrlIDC _control; private _ctrlIDC = ctrlIDC _control;

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeFillRightPanel = createProfileScope QFUNC(fillRightPanel);
#endif
params ["_display", "_control"]; params ["_display", "_control"];
private _ctrlIDC = ctrlIDC _control; private _ctrlIDC = ctrlIDC _control;

View File

@ -0,0 +1,319 @@
/*
* Author: Alganthe
* Handles the stats control group
*
* Arguments:
* 0: Arsenal display <DISPLAY>
* 1: Current panel control <CONTROL>
* 2: Current panel selection <SCALAR>
* 3: Item config entry <CONFIG>
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
#include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeHandleStats = createProfileScope QFUNC(handleStats);
#endif
params ["_display", "_control", "_curSel", "_itemCfg"];
private _statsBoxCtrl = _display displayCtrl IDC_statsBox;
private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage;
private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage;
private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage;
private _hideUnusedFnc = {
params ["_numbers"];
{
private _statsTitleCtrl = _display displayCtrl (5101 + ((_x - 1) * 4));
private _statsTitleIDC = ctrlIDC _statsTitleCtrl;
private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1);
private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2);
private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3);
{
_x ctrlSetFade 1;
_x ctrlCommit 0;
} forEach [
_statsTitleCtrl,
_statsBackgroundCtrl,
_statsBarCtrl,
_statsTextCtrl
];
} forEach _numbers;
};
if !(isNil "_itemCfg") then {
private _handleStatsFnc = {
params ["_statsIndex", "_leftPanel"];
// Get the proper list and page
if (_leftPanel) then {
[true, (uiNamespace getVariable QGVAR(statsListLeftPanel)) select _statsIndex, GVAR(statsPagesLeft) select _statsIndex]
} else {
[false, (uiNamespace getVariable QGVAR(statsListRightPanel)) select _statsIndex, GVAR(statsPagesRight) select _statsIndex]
} params ["_isLeftPanel", "_statsArray", "_currentPage"];
private _statsList = _statsArray select _currentPage;
private _statsCount = 0;
// Handle titles, bars and text
_statsList = _statsList select [0, 5];
if !(_statsList isEqualTo []) then {
{
_x params ["_ID", "_configEntry", "_title", "_bools", "_statements"];
_bools params ["_showBar", "_showText"];
_statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]];
private _statsTitleCtrl = _display displayCtrl (5101 + _forEachIndex * 4);
private _statsTitleIDC = ctrlIDC _statsTitleCtrl;
private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1);
private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2);
private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3);
_statsCount = _statsCount + 1;
_statsTitleCtrl ctrlSetText _title;
_statsTitleCtrl ctrlSetFade 0;
// Handle bars
if (_showBar) then {
_statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement);
_statsBackgroundCtrl ctrlSetFade 0;
_statsBarCtrl ctrlSetFade 0;
} else {
_statsBackgroundCtrl ctrlSetFade 1;
_statsBarCtrl ctrlSetFade 1;
};
// Handle text entries
if (_showText) then {
private _textStatementResult = [_configEntry, _itemCfg] call _textStatement;
if (_textStatementResult isEqualtype "") then {
_statsTextCtrl ctrlSetText _textStatementResult;
} else {
_statsTextCtrl ctrlSetText (str _textStatementResult);
};
_statsTextCtrl ctrlSetTextColor ([[1,1,1,1], [0,0,0,1]] select (_showBar));
_statsTextCtrl ctrlSetFade 0;
} else {
_statsTextCtrl ctrlSetFade 1;
};
{
_x ctrlCommit 0;
} forEach [
_statsTitleCtrl,
_statsBackgroundCtrl,
_statsBarCtrl,
_statsTextCtrl
];
} forEach (_statsList select {
_x params ["_ID","_configEntry", "_title", "_bools", "_statements"];
_statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]];
([_configEntry, _itemCfg] call _condition)
});
};
// Resize the window
switch (_statsCount) do {
case 0: {
[[1, 2, 3, 4, 5]] call _hideUnusedFnc;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
11 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
};
case 1: {
[[2, 3, 4, 5]] call _hideUnusedFnc;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
15 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
};
case 2: {
[[3, 4, 5]] call _hideUnusedFnc;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
25 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
};
case 3: {
[[4, 5]] call _hideUnusedFnc;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
35 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
};
case 4: {
[[5]] call _hideUnusedFnc;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
45 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
};
case 5: {
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
55 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
};
};
GVAR(statsInfo) = [_isLeftPanel, _statsIndex, _control, _curSel, _itemCfg];
// Toggle page buttons
_statsPreviousPageCtrl ctrlEnable !(_currentPage == 0);
_statsNextPageCtrl ctrlEnable !(_currentPage + 1 >= count _statsArray);
_statsCurrentPageCtrl ctrlSetText ([localize LSTRING(page), str (_currentPage + 1)] joinString " ");
{
_x ctrlSetFade 0;
_x ctrlCommit 0;
} forEach [
_statsPreviousPageCtrl,
_statsNextPageCtrl,
_statsCurrentPageCtrl
];
};
if (ctrlIDC _control == IDC_leftTabContent) then {
switch (GVAR(currentLeftPanel)) do {
case IDC_buttonPrimaryWeapon: {
[0, true] call _handleStatsFnc;
};
case IDC_buttonHandgun: {
[1, true] call _handleStatsFnc;
};
case IDC_buttonSecondaryWeapon: {
[2, true] call _handleStatsFnc;
};
case IDC_buttonUniform: {
[3, true] call _handleStatsFnc;
};
case IDC_buttonVest: {
[4, true] call _handleStatsFnc;
};
case IDC_buttonBackpack: {
[5, true] call _handleStatsFnc;
};
case IDC_buttonHeadgear: {
[6, true] call _handleStatsFnc;
};
case IDC_buttonGoggles: {
[7, true] call _handleStatsFnc;
};
case IDC_buttonNVG: {
[8, true] call _handleStatsFnc;
};
case IDC_buttonBinoculars: {
[9, true] call _handleStatsFnc;
};
case IDC_buttonMap: {
[10, true] call _handleStatsFnc;
};
case IDC_buttonGPS: {
[11, true] call _handleStatsFnc;
};
case IDC_buttonRadio: {
[12, true] call _handleStatsFnc;
};
case IDC_buttonCompass: {
[13, true] call _handleStatsFnc;
};
case IDC_buttonWatch: {
[14, true] call _handleStatsFnc;
};
case IDC_buttonFace: {
[15, true] call _handleStatsFnc;
};
case IDC_buttonVoice: {
[16, true] call _handleStatsFnc;
};
case IDC_buttonInsigna: {
[17, true] call _handleStatsFnc;
};
};
} else {
switch (GVAR(currentRightPanel)) do {
case IDC_buttonOptic: {
[0, false] call _handleStatsFnc;
};
case IDC_buttonItemAcc: {
[1, false] call _handleStatsFnc;
};
case IDC_buttonMuzzle: {
[2, false] call _handleStatsFnc;
};
case IDC_buttonBipod: {
[3, false] call _handleStatsFnc;
};
case IDC_buttonCurrentMag;
case IDC_buttonCurrentMag2;
case IDC_buttonMag;
case IDC_buttonMagALL: {
[4, false] call _handleStatsFnc;
};
case IDC_buttonThrow: {
[5, false] call _handleStatsFnc;
};
case IDC_buttonPut: {
[6, false] call _handleStatsFnc;
};
case IDC_buttonMisc: {
[7, false] call _handleStatsFnc;
};
};
};
} else {
[[1, 2, 3, 4, 5]] call _hideUnusedFnc;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
11 * GRID_H
];
_statsBoxCtrl ctrlCommit 0;
{
_x ctrlSetFade 1;
_x ctrlCommit 0;
} forEach [
_statsPreviousPageCtrl,
_statsNextPageCtrl,
_statsCurrentPageCtrl
];
};

View File

@ -16,6 +16,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeItemInfo = createProfileScope QFUNC(itemInfo);
#endif
params ["_display", "_control", "_curSel" ,"_itemCfg"]; params ["_display", "_control", "_curSel" ,"_itemCfg"];
private _ctrlInfo = _display displayCtrl IDC_infoBox; private _ctrlInfo = _display displayCtrl IDC_infoBox;
@ -25,6 +29,8 @@ if (isClass _itemCfg) then {
_ctrlInfo ctrlSetFade 0; _ctrlInfo ctrlSetFade 0;
_ctrlInfo ctrlCommit FADE_DELAY; _ctrlInfo ctrlCommit FADE_DELAY;
[QGVAR(displayStats), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent;
// Name + author // Name + author
private _ctrlInfoName = _display displayCtrl IDC_infoName; private _ctrlInfoName = _display displayCtrl IDC_infoName;
_ctrlInfoName ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == 102)); _ctrlInfoName ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == 102));
@ -70,6 +76,8 @@ if (isClass _itemCfg) then {
_ctrlDLCBackground ctrlcommit 0; _ctrlDLCBackground ctrlcommit 0;
} else { } else {
[QGVAR(displayStats), [_display, _control, -1, nil]] call CBA_fnc_localEvent;
_ctrlInfo ctrlSetFade 1; _ctrlInfo ctrlSetFade 1;
_ctrlInfo ctrlCommit FADE_DELAY; _ctrlInfo ctrlCommit FADE_DELAY;
}; };

View File

@ -98,6 +98,11 @@ GVAR(currentVoice) = nil;
GVAR(currentInsignia) = nil; GVAR(currentInsignia) = nil;
GVAR(currentAction) = nil; GVAR(currentAction) = nil;
GVAR(showStats) = nil;
GVAR(statsPagesLeft) = nil;
GVAR(statsPagesRight) = nil;
GVAR(statsInfo) = nil;
GVAR(center) = nil; GVAR(center) = nil;
GVAR(centerNotPlayer) = nil; GVAR(centerNotPlayer) = nil;

View File

@ -15,6 +15,11 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeArsenal = createProfileScope QFUNC(onArsenalOpen);
profilerTrigger;
#endif
params ["", "_args"]; params ["", "_args"];
_args params ["_display"]; _args params ["_display"];
@ -55,6 +60,11 @@ GVAR(currentInsignia) = GVAR(center) param [0, objNull, [objNull]] getVariable [
GVAR(currentAction) = "Stand"; GVAR(currentAction) = "Stand";
GVAR(shiftState) = false; GVAR(shiftState) = false;
GVAR(showStats) = true;
GVAR(statsPagesLeft) = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
GVAR(statsPagesRight) = [0, 0, 0, 0, 0, 0, 0, 0];
GVAR(statsInfo) = [true, 0, controlNull, nil, nil];
// Add the items the player has to virtualItems // Add the items the player has to virtualItems
for "_index" from 0 to 10 do { for "_index" from 0 to 10 do {
switch (_index) do { switch (_index) do {
@ -199,6 +209,20 @@ _mouseBlockCtrl ctrlEnable false;
IDC_rightSearchbar IDC_rightSearchbar
]; ];
// Handle stats
private _statsBoxCtrl = _display displayCtrl IDC_statsBox;
_statsBoxCtrl ctrlSetPosition [
(0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP,
safezoneY + 1.8 * GRID_H,
47 * GRID_W,
11 * GRID_H
];
_statsBoxCtrl ctrlEnable false;
_statsBoxCtrl ctrlCommit 0;
(_display displayCtrl IDC_statsButton) ctrlShow false;
// Disable import in MP
if (isMultiplayer) then { if (isMultiplayer) then {
private _importButtonCtrl = _display displayCtrl IDC_buttonImport; private _importButtonCtrl = _display displayCtrl IDC_buttonImport;
_importButtonCtrl ctrlEnable false; _importButtonCtrl ctrlEnable false;

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeOnSelChangedLeft = createProfileScope QFUNC(onSelChangedLeft);
#endif
params ["_control", "_curSel"]; params ["_control", "_curSel"];
if (_curSel < 0) exitwith {}; if (_curSel < 0) exitwith {};

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeOnSelChangedRight = createProfileScope QFUNC(onSelChangedRight);
#endif
params ["_control", "_curSel"]; params ["_control", "_curSel"];
if (_curSel < 0) exitwith {}; if (_curSel < 0) exitwith {};

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeOnSelChangedRightLNB = createProfileScope QFUNC(onSelChangedRightListnBox);
#endif
params ["_control", "_curSel"]; params ["_control", "_curSel"];
if (_curSel < 0) exitwith {}; if (_curSel < 0) exitwith {};

View File

@ -0,0 +1,66 @@
/*
* Author: Alganthe
* Remove a stat from ACE Arsenal.
*
* Arguments:
* 0: Array of IDs (ARRAY)
*
* Return Value:
* None
*
* Example:
* [["scopeStatL00","scopeStatL01","scopeStatL02","scopeStatR07"]] call ace_arsenal_fnc_removeStat;
*
* Public: Yes
*/
#include "script_component.hpp"
params ["_IDList"];
private _statsListLeftPanel = uiNamespace getVariable QGVAR(statsListLeftPanel);
private _statsListRightPanel = uiNamespace getVariable QGVAR(statsListRightPanel);
{
private _currentID = _x;
private _stringCount = count _currentID;
private _side = _currentID select [_stringCount - 3, 1];
private _tab = _currentID select [_stringCount - 2, 2];
_tab = parseNumber _tab;
private _tabToChange = if (_side == "R") then {
_statsListRightPanel select _tab
} else {
_statsListLeftPanel select _tab
};
{
private _currentPage = _x;
{
if (_x select 0 == _currentID) then {
_currentPage deleteAt _forEachIndex;
};
} foreach _currentPage;
} foreach _tabToChange;
} foreach _IDList;
// Clear empty pages
private _fnc_deleteEmptyPage = {
{
private _evaluatedTab = _forEachIndex;
{
if (count _x == 0) then {
_markedForDeletion pushBack [_evaluatedTab, _forEachIndex];
};
} foreach _x;
{
(_statsListLeftPanel select (_x select 0)) deleteAt (_x select 1);
} foreach _markedForDeletion;
} foreach (_this select 0);
};
private _markedForDeletion = [];
[_statsListLeftPanel] call _fnc_deleteEmptyPage;
[_statsListRightPanel] call _fnc_deleteEmptyPage;

View File

@ -13,6 +13,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeShowItem = createProfileScope QFUNC(showItem);
#endif
if (GVAR(centerNotPlayer)) exitWith {}; if (GVAR(centerNotPlayer)) exitWith {};
private _nextAction = switch (GVAR(currentLeftPanel)) do { private _nextAction = switch (GVAR(currentLeftPanel)) do {

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeSortPanel = createProfileScope QFUNC(sortPanel);
#endif
params ["_control", "_mode"]; params ["_control", "_mode"];
private _display = ctrlParent _control; private _display = ctrlParent _control;

View File

@ -0,0 +1,30 @@
/*
* Author: Alganthe
* Generic bar statement for stats.
*
* Arguments:
* 0: stat (STRING)
* 1: item config path (CONFIG)
* 2: Args for configExtreme
* 2.1: Stat limits (ARRAY of BOOL)
* 2.2: Bar limits (ARRAY of SCALAR)
* 2.3: Evaluate as a logarithmic number (BOOL)
*
* Return Value:
* Number
*
* Public: Yes
*/
#include "script_component.hpp"
params ["_stat", "_config", "_args"];
_args params ["_statMinMax", "_barLimits", "_configExtremeBool"];
private _statValues = [
[_config],
[_stat],
[_configExtremeBool],
[_statMinMax select 0]
] call BIS_fnc_configExtremes;
linearConversion [_statMinMax select 0, _statMinMax select 1, (_statValues select 1) select 0, _barLimits select 0, _barLimits select 1]

View File

@ -0,0 +1,34 @@
/*
* Author: Alganthe
* Impact bar statement.
*
* Arguments:
* 0: stats array (ARRAY)
* 1: item config path (CONFIG)
* 2: Args for configExtreme
* 2.1: Stat limits (ARRAY of BOOL)
* 2.2: Bar limits (ARRAY of SCALAR)
* 2.3: Evaluate as a logarithmic number (BOOL)
*
* Return Value:
* Number
*
* Public: No
*/
#include "script_component.hpp"
params ["_stats", "_config", "_args"];
_args params ["_hitMinMax", "_initSpeedMinMax", "_launcherTabIDC"];
private _statValues = [
[_config],
_stats,
[true, false],
[_hitMinMax select 0, _initSpeedMinMax select 0]
] call BIS_fnc_configExtremes;
(_statValues select 1) params ["_hit", "_initSpeed"];
_hit = linearConversion [_hitMinMax select 0, _hitMinMax select 1, _hit, 0.01, 1];
_initSpeed = linearConversion [_initSpeedMinMax select 0, _initSpeedMinMax select 1, _initSpeed, 0.01, 1];
[sqrt(_hit^2 * _initSpeed), _hit] select (GVAR(currentLeftPanel) == _launcherTabIDC)

View File

@ -0,0 +1,31 @@
/*
* Author: Alganthe
* Accuracy text statement.
*
* Arguments:
* 0: stat (STRING)
* 1: item config path (CONFIG)
* 2: Args for configExtreme
* 2.1: Stat limits (ARRAY of BOOL)
* 2.2: Evaluate as a logarithmic number (BOOL)
*
* Return Value:
* Number
*
* Public: No
*/
#include "script_component.hpp"
params ["_stat", "_config", "_args"];
_args params ["_statMinMax", "_configExtremeBool"];
private _statValues = [
[_config],
[_stat],
[_configExtremeBool],
[_statMinMax select 0]
] call BIS_fnc_configExtremes;
private _dispersion = (_statValues select 1) select 0;
format ["%1 MIL (%2 MOA)", (_dispersion * 1000) toFixed 2, (_dispersion / pi * 10800) ToFixed 1];

View File

@ -0,0 +1,28 @@
/*
* Author: Alganthe
* Text statement for the mass stat.
*
* Arguments:
* 0: not used
* 1: item config path (CONFIG)
*
* Return Value:
* String to display
*
* Public: No
*/
#include "script_component.hpp"
params ["", "_config"];
private _mass = getNumber (_config >> "mass");
if (_mass == 0 && {isClass (_config >> "WeaponSlotsInfo")}) then {
_mass = getNumber (_config >> "WeaponSlotsInfo" >> "mass");
};
if (_mass == 0 && {isClass (_config >> "itemInfo")}) then {
_mass = getNumber (_config >> "itemInfo" >> "mass");
};
format ["%1kg (%2lb)",((_mass * 0.1 * (1/2.2046) * 100) / 100) ToFixed 2, ((_mass * 0.1 * 100) / 100) ToFixed 2]

View File

@ -0,0 +1,29 @@
/*
* Author: Alganthe
* ROF text statement.
*
* Arguments:
* 0: stat (STRING)
* 1: item config path (CONFIG)
* 2: Args for configExtreme
* 2.1: Stat limits (ARRAY of BOOL)
* 2.2: Evaluate as a logarithmic number (BOOL)
*
* Return Value:
* Number
*
* Public: No
*/
#include "script_component.hpp"
params ["_stat", "_config", "_args"];
_args params ["_statMinMax", "_configExtremeBool"];
private _statValues = [
[_config],
[_stat],
[_configExtremeBool],
[_statMinMax select 0]
] call BIS_fnc_configExtremes;
format ["%1 rpm", round (60 / ((_statValues select 1) select 0))]

View File

@ -14,6 +14,10 @@
#include "script_component.hpp" #include "script_component.hpp"
#include "..\defines.hpp" #include "..\defines.hpp"
#ifdef ENABLE_PERF_PROFILING
private _scopeUpdateRightPanel = createProfileScope QFUNC(updateRightPanel);
#endif
params ["_control", "_maxLoad"]; params ["_control", "_maxLoad"];
private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar;

View File

@ -60,13 +60,13 @@ private _fnc_weaponCheck = {
if (isClass (_magCfg >> _mag)) then { if (isClass (_magCfg >> _mag)) then {
if !(_mag in (GVAR(virtualItems) select 2)) then { if !(_mag in (GVAR(virtualItems) select 2)) then {
_unavailableItemsList pushBackUnique _item; _unavailableItemsList pushBackUnique _mag;
_dataPath set [_forEachIndex, []]; _dataPath set [_forEachIndex, []];
_unavailableItemsAmount = _unavailableItemsAmount + 1; _unavailableItemsAmount = _unavailableItemsAmount + 1;
}; };
} else { } else {
_nullItemsList pushBackUnique _item; _nullItemsList pushBackUnique _mag;
_dataPath set [_forEachIndex, []]; _dataPath set [_forEachIndex, []];
_nullItemsAmount = _nullItemsAmount + 1; _nullItemsAmount = _nullItemsAmount + 1;
}; };

View File

@ -5,6 +5,7 @@
// #define DEBUG_MODE_FULL // #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE // #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS // #define ENABLE_PERFORMANCE_COUNTERS
// #define ENABLE_PERF_PROFILING // This requires https://forums.bohemia.net/forums/topic/211626-arma-script-profiler/ do not uncomment otherwise.
#ifdef DEBUG_ENABLED_ARSENAL #ifdef DEBUG_ENABLED_ARSENAL
#define DEBUG_MODE_FULL #define DEBUG_MODE_FULL

View File

@ -682,6 +682,14 @@
<Chinese>匯入當前/預設的裝備</Chinese> <Chinese>匯入當前/預設的裝備</Chinese>
<Chinesesimp>汇入当前/预设的装备</Chinesesimp> <Chinesesimp>汇入当前/预设的装备</Chinesesimp>
</Key> </Key>
<Key ID="STR_ACE_Arsenal_statPotassium">
<English>Potassium levels</English>
<French>Taux de potassium</French>
</Key>
<Key ID="STR_ACE_Arsenal_page">
<English>Page</English>
<French>Page</French>
</Key>
<Key ID="STR_ACE_Arsenal_enableIdentityTabsSettings"> <Key ID="STR_ACE_Arsenal_enableIdentityTabsSettings">
<English>Enable the faces / voices / insignias tabs</English> <English>Enable the faces / voices / insignias tabs</English>
<French>Activer les onglets faces / voix / insignes</French> <French>Activer les onglets faces / voix / insignes</French>

View File

@ -42,7 +42,7 @@ class GVAR(display) {
idc = IDC_arrowMinus; idc = IDC_arrowMinus;
text = "-"; text = "-";
colorBackground[]={0,0,0,0.8}; colorBackground[]={0,0,0,0.8};
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), -1)] call FUNC(buttonCargo)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), -1)] call FUNC(buttonCargo));
fade = 1; fade = 1;
enable = 0; enable = 0;
x = 0.5; x = 0.5;
@ -53,7 +53,7 @@ class GVAR(display) {
}; };
class ArrowRight: ArrowLeft { class ArrowRight: ArrowLeft {
idc = IDC_arrowPlus; idc = IDC_arrowPlus;
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), 1)] call FUNC(buttonCargo)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), 1)] call FUNC(buttonCargo));
text="+"; text="+";
}; };
class blockLeftFrame: RscFrame { class blockLeftFrame: RscFrame {
@ -177,7 +177,7 @@ class GVAR(display) {
sizeEx = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H);
shortcuts[] = {"0x0E"}; shortcuts[] = {"0x0E"};
tooltip = CSTRING(buttonHideTooltip); tooltip = CSTRING(buttonHideTooltip);
onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonHide)); onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonHide));
}; };
class buttonLoadouts: buttonHide { class buttonLoadouts: buttonHide {
idc = IDC_buttonLoadouts; idc = IDC_buttonLoadouts;
@ -191,14 +191,14 @@ class GVAR(display) {
x = QUOTE(3 * WIDTH_GAP + 2 * WIDTH_SINGLE); x = QUOTE(3 * WIDTH_GAP + 2 * WIDTH_SINGLE);
text = CSTRING(buttonExportText); text = CSTRING(buttonExportText);
tooltip = CSTRING(buttonExportTooltip); tooltip = CSTRING(buttonExportTooltip);
onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonExport)); onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonExport));
}; };
class buttonImport: buttonHide { class buttonImport: buttonHide {
idc = IDC_buttonImport; idc = IDC_buttonImport;
x = QUOTE(4 * WIDTH_GAP + 3 * WIDTH_SINGLE); x = QUOTE(4 * WIDTH_GAP + 3 * WIDTH_SINGLE);
text = CSTRING(buttonImportText); text = CSTRING(buttonImportText);
tooltip = CSTRING(buttonImportTooltip); tooltip = CSTRING(buttonImportTooltip);
onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonImport)); onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonImport));
}; };
class buttonClose: ctrlButtonOK { class buttonClose: ctrlButtonOK {
idc = IDC_menuBarClose; idc = IDC_menuBarClose;
@ -209,7 +209,7 @@ class GVAR(display) {
h = QUOTE(7 * GRID_H); h = QUOTE(7 * GRID_H);
text = CSTRING(buttonCloseText); text = CSTRING(buttonCloseText);
sizeEx = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H);
onButtonClick = QUOTE(ctrlparent (_this select 0) closeDisplay 1); onButtonClick = QUOTE(ctrlParent (_this select 0) closeDisplay 1);
}; };
}; };
}; };
@ -268,6 +268,194 @@ class GVAR(display) {
}; };
}; };
}; };
class statsBox: RscControlsGroupNoScrollbars {
idc = IDC_statsBox;
x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP);
y = QUOTE(safezoneY + 1.8 * GRID_H);
w = QUOTE(47 * GRID_W);
h = QUOTE(55 * GRID_H);
class controls {
class statsStaticBackground1: ctrlStaticBackground {
idc = -1;
x = QUOTE(0);
y = QUOTE(0);
w = QUOTE(47 * GRID_W);
h = QUOTE(55 * GRID_H);
colorBackground[]={0.1,0.1,0.1,0.5};
};
class statsStaticBackground2: ctrlStaticBackground {
idc = -1;
x = QUOTE(0);
y = QUOTE(0);
w = QUOTE(47 * GRID_W);
h = QUOTE(5 * GRID_H);
colorBackground[]={0.1,0.1,0.1,0.8};
};
class statsTitle1: RscText {
idc = IDC_statsTitle1;
fade = 1;
x = QUOTE(0 * GRID_W);
y = QUOTE(5 * GRID_H);
w = QUOTE(45 * GRID_W);
h = QUOTE(5 * GRID_H);
colorBackground[]={0,0,0,0};
colorText[]={0.7,0.7,0.7,1};
sizeEx = QUOTE(5 * GRID_H);
text = "";
};
class statsBackground1: ctrlStaticBackground {
idc = IDC_statsBackground1;
fade = 1;
x = QUOTE(1 * GRID_W);
y = QUOTE(10 * GRID_H);
w = QUOTE(45 * GRID_W);
h = QUOTE(4 * GRID_H);
colorBackground[]={1,1,1,0.15};
};
class statsBar1: ctrlProgress {
idc = IDC_statsBar1;
fade = 1;
style = 0;
texture = "#(argb,8,8,3)color(1,1,1,1)";
colorBar[] = {1,1,1,1};
colorFrame[] = {0,0,0,0};
x = QUOTE(1 * GRID_W);
y = QUOTE(10 * GRID_H);
w = QUOTE(45 * GRID_W);
h = QUOTE(4 * GRID_H);
};
class statsText1: RscText {
idc = IDC_statsText1;
shadow=0;
fade = 1;
colorShadow[]={1,1,1,1};
colorText[]={0,0,0,1};
x = QUOTE(0 * GRID_W);
y = QUOTE(10 * GRID_H);
w = QUOTE(45 * GRID_W);
h = QUOTE(4 * GRID_H);
sizeEx = QUOTE(5 * GRID_H);
text = "";
};
class statsTitle2: statsTitle1 {
idc = IDC_statsTitle2;
y = QUOTE(15 * GRID_H);
};
class statsBackground2: statsBackground1 {
idc = IDC_statsBackground2;
y = QUOTE(20 * GRID_H);
};
class statsBar2: statsBar1 {
idc = IDC_statsBar2;
y = QUOTE(20 * GRID_H);
};
class statsText2: statsText1 {
idc = IDC_statsText2;
y = QUOTE(20 * GRID_H);
};
class statsTitle3: statsTitle1 {
idc = IDC_statsTitle3;
y = QUOTE(25 * GRID_H);
};
class statsBackground3: statsBackground1 {
idc = IDC_statsBackground3;
y = QUOTE(30 * GRID_H);
};
class statsBar3: statsBar1 {
idc = IDC_statsBar3;
y = QUOTE(30 * GRID_H);
};
class statsText3: statsText1 {
idc = IDC_statsText3;
y = QUOTE(30 * GRID_H);
};
class statsTitle4: statsTitle1 {
idc = IDC_statsTitle4;
y = QUOTE(35 * GRID_H);
};
class statsBackground4: statsBackground1 {
idc = IDC_statsBackground4;
y = QUOTE(40 * GRID_H);
};
class statsBar4: statsBar1 {
idc = IDC_statsBar4;
y = QUOTE(40 * GRID_H);
};
class statsText4: statsText1 {
idc = IDC_statsText4;
y = QUOTE(40 * GRID_H);
};
class statsTitle5: statsTitle1 {
idc = IDC_statsTitle5;
y = QUOTE(45 * GRID_H);
};
class statsBackground5: statsBackground1 {
idc = IDC_statsBackground5;
y = QUOTE(50 * GRID_H);
};
class statsBar5: statsBar1 {
idc = IDC_statsBar5;
y = QUOTE(50 * GRID_H);
colorBackground[]={1,1,1,0.15};
};
class statsText5: statsText1 {
idc = IDC_statsText5;
y = QUOTE(50 * GRID_H);
};
};
};
class statsButton: ctrlButton {
idc = IDC_statsButton;
style= 2;
text=">";
onButtonClick = QUOTE(ARR_2([QQGVAR(statsButton), [ctrlParent (_this select 0)]]) call CBA_fnc_localEvent);
x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP);
y = QUOTE(safezoneY + 1.8 * GRID_H);
w = QUOTE(6 * GRID_W);
h = QUOTE(6 * GRID_H);
sizeEx = QUOTE(5 * GRID_H)
};
class statsPreviousPage: ctrlButton {
idc = IDC_statsPreviousPage;
style= 2;
text="<";
colorBackground[]={0,0,0,0};
colorBackgroundDisabled[]= {0,0,0,0};
onButtonClick = QUOTE(ARR_2([QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0), _this select 0, false)]]) call CBA_fnc_localEvent);
x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP);
y = QUOTE(safezoneY + 1.8 * GRID_H);
w = QUOTE(5 * GRID_W);
h = QUOTE(5 * GRID_H);
sizeEx = QUOTE(5.5 * GRID_H)
};
class statsNextPage: statsPreviousPage {
idc = IDC_statsNextPage;
text = ">"
onButtonClick = QUOTE(ARR_2([QQGVAR(statsChangePage),[ARR_3(ctrlParent (_this select 0), _this select 0, true)]]) call CBA_fnc_localEvent);
x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 30 * GRID_W);
};
class statsCurrentPage: RscText {
idc = IDC_statsCurrentPage;
style = ST_CENTER;
x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 5 * GRID_W);
y = QUOTE(safezoneY + 1.8 * GRID_H);
w = QUOTE(25 * GRID_W);
h = QUOTE(5 * GRID_H);
colorBackground[]={0,0,0,0};
shadow=2;
sizeEx = QUOTE(5 * GRID_H);
text = "";
};
class statsButtonClose: ctrlButtonPicture {
idc = IDC_statsButtonClose;
colorBackground[]={0,0,0,0};
text="\a3\3DEN\Data\Displays\Display3DEN\search_end_ca.paa";
onButtonClick = QUOTE(ARR_2([QQGVAR(statsButton), [ctrlParent (_this select 0)]]) call CBA_fnc_localEvent);
x = QUOTE((0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP + 42 * GRID_W);
y = QUOTE(safezoneY + 1.8 * GRID_H);
w = QUOTE(5 * GRID_W);
h = QUOTE(5 * GRID_H);
};
class mouseBlock: RscText { class mouseBlock: RscText {
idc = IDC_mouseBlock; idc = IDC_mouseBlock;
style = 16; style = 16;
@ -376,7 +564,7 @@ class GVAR(display) {
idc = IDC_leftSearchbarButton; idc = IDC_leftSearchbarButton;
text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa";
colorBackground[]={0,0,0,0.5}; colorBackground[]={0,0,0,0.5};
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), ctrlparent (_this select 0) displayCtrl IDC_leftSearchbar)] call FUNC(handleSearchbar)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_leftSearchbar)] call FUNC(handleSearchbar));
x = QUOTE(safezoneX + 87 * GRID_W); x = QUOTE(safezoneX + 87 * GRID_W);
y = QUOTE(safezoneY + 1.8 * GRID_H); y = QUOTE(safezoneY + 1.8 * GRID_H);
w = QUOTE(6 * GRID_W); w = QUOTE(6 * GRID_W);
@ -390,7 +578,7 @@ class GVAR(display) {
}; };
class rightSearchbarButton: leftSearchbarButton { class rightSearchbarButton: leftSearchbarButton {
idc = IDC_rightSearchbarButton; idc = IDC_rightSearchbarButton;
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), ctrlparent (_this select 0) displayCtrl IDC_rightSearchbar)] call FUNC(handleSearchbar)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_rightSearchbar)] call FUNC(handleSearchbar));
x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); x = QUOTE(safezoneX + safezoneW - 93 * GRID_W);
}; };
class tabLeft: RscControlsGroupNoScrollbars { class tabLeft: RscControlsGroupNoScrollbars {
@ -414,7 +602,7 @@ class GVAR(display) {
idc = IDC_buttonPrimaryWeapon; idc = IDC_buttonPrimaryWeapon;
text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa"; text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa";
tooltip="$STR_A3_RscDisplayArsenal_tab_PrimaryWeapon"; tooltip="$STR_A3_RscDisplayArsenal_tab_PrimaryWeapon";
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(fillLeftPanel)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(fillLeftPanel));
colorBackground[]={0,0,0,0.5}; colorBackground[]={0,0,0,0.5};
x = QUOTE(0 * GRID_W); x = QUOTE(0 * GRID_W);
y = QUOTE(0 * GRID_H); y = QUOTE(0 * GRID_H);
@ -607,7 +795,7 @@ class GVAR(display) {
idc = IDC_buttonOptic; idc = IDC_buttonOptic;
tooltip="$STR_A3_RscDisplayArsenal_tab_ItemOptic"; tooltip="$STR_A3_RscDisplayArsenal_tab_ItemOptic";
text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa"; text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa";
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(fillRightPanel)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(fillRightPanel));
colorBackground[]={0,0,0,0.5}; colorBackground[]={0,0,0,0.5};
x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); x = QUOTE(safezoneW + safezoneX - 10 * GRID_W);
y = QUOTE(safezoneY + 8 * GRID_H); y = QUOTE(safezoneY + 8 * GRID_H);
@ -776,7 +964,7 @@ class GVAR(loadoutsDisplay) {
onSetFocus = QUOTE(GVAR(loadoutsPanelFocus) = true); onSetFocus = QUOTE(GVAR(loadoutsPanelFocus) = true);
onKillFocus = QUOTE(GVAR(loadoutsPanelFocus) = false); onKillFocus = QUOTE(GVAR(loadoutsPanelFocus) = false);
onLBSelChanged = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(onSelChangedLoadouts)); onLBSelChanged = QUOTE([ARR_3(ctrlParent (_this select 0), _this select 0, _this select 1)] call FUNC(onSelChangedLoadouts));
onLBDblClick = QUOTE([ARR_2(ctrlparent (_this select 0), (ctrlParent (_this select 0)) displayCtrl IDC_buttonLoad)] call FUNC(buttonLoadoutsLoad)); onLBDblClick = QUOTE([ARR_2(ctrlParent (_this select 0), (ctrlParent (_this select 0)) displayCtrl IDC_buttonLoad)] call FUNC(buttonLoadoutsLoad));
x = QUOTE(0); x = QUOTE(0);
y = QUOTE(5 * GRID_H); y = QUOTE(5 * GRID_H);
w = QUOTE(160 * GRID_W); w = QUOTE(160 * GRID_W);
@ -814,7 +1002,7 @@ class GVAR(loadoutsDisplay) {
idc = -1; idc = -1;
text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa";
colorBackground[]={0,0,0,0.5}; colorBackground[]={0,0,0,0.5};
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), ctrlparent (_this select 0) displayCtrl IDC_loadoutsSearchbar)] call FUNC(handleLoadoutsSearchbar)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_loadoutsSearchbar)] call FUNC(handleLoadoutsSearchbar));
x = QUOTE(155 * GRID_W); x = QUOTE(155 * GRID_W);
y = QUOTE(safezoneH - (51 * GRID_H)); y = QUOTE(safezoneH - (51 * GRID_H));
w = QUOTE(5 * GRID_W); w = QUOTE(5 * GRID_W);
@ -829,7 +1017,7 @@ class GVAR(loadoutsDisplay) {
text= CSTRING(buttonSaveText); text= CSTRING(buttonSaveText);
tooltip= CSTRING(buttonSaveTooltip); tooltip= CSTRING(buttonSaveTooltip);
sizeEx = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H);
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsSave)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsSave));
colorBackground[] = {0,0,0,0.8}; colorBackground[] = {0,0,0,0.8};
}; };
class buttonRename: buttonSave { class buttonRename: buttonSave {
@ -837,21 +1025,21 @@ class GVAR(loadoutsDisplay) {
x = QUOTE(32.5 * GRID_W); x = QUOTE(32.5 * GRID_W);
text= CSTRING(buttonRenameText); text= CSTRING(buttonRenameText);
tooltip= CSTRING(buttonRenameTooltip); tooltip= CSTRING(buttonRenameTooltip);
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsRename)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsRename));
}; };
class buttonLoad: buttonSave { class buttonLoad: buttonSave {
idc = IDC_buttonLoad; idc = IDC_buttonLoad;
x = QUOTE(65 * GRID_W); x = QUOTE(65 * GRID_W);
text= CSTRING(buttonLoadText); text= CSTRING(buttonLoadText);
tooltip= CSTRING(buttonLoadTooltip); tooltip= CSTRING(buttonLoadTooltip);
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsLoad)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsLoad));
}; };
class buttonShare: buttonSave { class buttonShare: buttonSave {
idc = IDC_buttonShare; idc = IDC_buttonShare;
x = QUOTE(97.5 * GRID_W); x = QUOTE(97.5 * GRID_W);
text= CSTRING(buttonSharePrivateText); text= CSTRING(buttonSharePrivateText);
tooltip= CSTRING(buttonShareTooltip); tooltip= CSTRING(buttonShareTooltip);
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsShare)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsShare));
}; };
class buttonDelete: buttonSave { class buttonDelete: buttonSave {
idc = IDC_buttonDelete; idc = IDC_buttonDelete;
@ -859,11 +1047,10 @@ class GVAR(loadoutsDisplay) {
text= CSTRING(buttonDeleteText); text= CSTRING(buttonDeleteText);
tooltip= CSTRING(buttonDeleteTooltip); tooltip= CSTRING(buttonDeleteTooltip);
colorBackgroundActive[] = {0.5,0,0,1}; colorBackgroundActive[] = {0.5,0,0,1};
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsDelete)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsDelete));
}; };
}; };
}; };
class buttonClose: ctrlButton { class buttonClose: ctrlButton {
idc = -1; idc = -1;
x = QUOTE(safezoneW + safezoneX - 32 * GRID_W); x = QUOTE(safezoneW + safezoneX - 32 * GRID_W);
@ -874,7 +1061,7 @@ class GVAR(loadoutsDisplay) {
text= CSTRING(buttonCloseText); text= CSTRING(buttonCloseText);
shortcuts[]= {"0x01"}; shortcuts[]= {"0x01"};
tooltip= ""; tooltip= "";
onButtonClick = QUOTE(ctrlparent (_this select 0) closeDisplay 2); onButtonClick = QUOTE(ctrlParent (_this select 0) closeDisplay 2);
}; };
class buttonBar: ctrlControlsGroupNoScrollbars { class buttonBar: ctrlControlsGroupNoScrollbars {
idc = -1; idc = -1;
@ -901,7 +1088,7 @@ class GVAR(loadoutsDisplay) {
sizeEx = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H);
text= CSTRING(tabMyLoadoutsText); text= CSTRING(tabMyLoadoutsText);
tooltip= CSTRING(tabMyLoadoutsTooltip); tooltip= CSTRING(tabMyLoadoutsTooltip);
onButtonClick = QUOTE([ARR_2(ctrlparent (_this select 0), _this select 0)] call FUNC(loadoutsChangeTab)); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(loadoutsChangeTab));
}; };
class buttonDefaultLoadoutsBackground: buttonMyLoadoutsBackground { class buttonDefaultLoadoutsBackground: buttonMyLoadoutsBackground {
idc = IDC_buttonDefaultLoadoutsBackground; idc = IDC_buttonDefaultLoadoutsBackground;

View File

@ -0,0 +1,66 @@
class EGVAR(arsenal,stats) {
class statBase;
class ACE_barrelTwist: statBase {
scope = 2;
priority = 1;
stats[] = {"ACE_barrelTwist"};
displayName= CSTRING(statBarrelTwist);
showText = 1;
textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _barrelTwist = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelTwist toFixed 0, (_barrelTwist / 25.4) toFixed 1)]);
tabs[] = {{0,1}, {}};
};
class ACE_barrelLength: statBase {
scope = 2;
priority = 0;
stats[] = {"ACE_barrelLength"};
displayName = CSTRING(statBarrelLength);
showText = 1;
textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _barrelLength = getNumber (_config >> _stat select 0); format [ARR_3('%1mm (%2in)',_barrelLength toFixed 0, (_barrelLength / 25.4) toFixed 1)]);
tabs[] = {{0,1}, {}};
};
class ACE_ammo: statBase {
scope = 2;
priority = 5;
stats[] = {"ammo", "displayName"};
displayName = "$STR_dn_ammo";
showText = 1;
textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _ammoDisplayName = getText (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 1); [ARR_2(_ammoDisplayName, getText (_config >> _stat select 0))] select (_ammoDisplayName == ''));
tabs[] = {{}, {4}};
};
class ACE_ballisticCoef: statBase {
scope = 2;
priority = 4;
stats[] = {"ACE_dragModel","ACE_ballisticCoefficients", "ACE_standardAtmosphere"};
displayName= CSTRING(statBallisticCoef);
showText= 1;
textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoCfg = (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo'))); private _ballisticCoef = getArray (_ammoCfg >> _stat select 1); _ballisticCoef sort false; format [ARR_4('%1 G%2 (%3)', _ballisticCoef select 0 ,getNumber (_ammoCfg >> _stat select 0), getText (_ammoCfg >> _stat select 2))]);
tabs[] ={{}, {4}};
};
class ACE_bulletMass: statBase {
scope = 2;
priority = 3;
stats[] = {"ACE_bulletMass"};
displayName = CSTRING(statBulletMass);
showText = 1;
textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _ammoWeight = getNumber (configFile >> 'CfgAmmo' >> (getText (_config >> 'ammo')) >> _stat select 0); format [ARR_3('%1g (%2gr)', _ammoWeight toFixed 1, (_ammoWeight * 15.43) toFixed 1)]);
tabs[] = {{}, {4}};
};
class ACE_magMuzzleVelocity: statBase {
scope = 2;
priority = 3;
stats[] = {"initSpeed"};
displayName= CSTRING(statMuzzleVelocity);
showText= 1;
textStatement = QUOTE(params[ARR_2('_stat', '_config')]; private _initSpeed = getNumber (_config >> _stat select 0); format [ARR_3('%1 m/s (%2 ft/s)', _initSpeed, (_initSpeed * 3.28084) toFixed 0)]);
tabs[] = {{}, {4}};
};
class ACE_weaponMuzzleVelocity: statBase {
scope = 2;
priority = 3;
stats[] = {"initSpeed"};
displayName= CSTRING(statMuzzleVelocity);
showText = 1;
textStatement = QUOTE([ARR_2(_this select 0, _this select 1)] call FUNC(statTextStatement_weaponMuzzleVelocity));
tabs[] = {{0,1}, {}};
};
};

View File

@ -0,0 +1,11 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preStart));
};
};
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preInit));
};
};

View File

@ -0,0 +1 @@
PREP(statTextStatement_weaponMuzzleVelocity);

View File

@ -0,0 +1,7 @@
#include "script_component.hpp"
ADDON = false;
PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

View File

@ -0,0 +1,3 @@
#include "script_component.hpp"
#include "XEH_PREP.hpp"

View File

@ -14,7 +14,9 @@ class CfgPatches {
}; };
}; };
#include "CfgEventHandlers.hpp"
#include "CfgAmmo.hpp" #include "CfgAmmo.hpp"
#include "CfgMagazines.hpp" #include "CfgMagazines.hpp"
#include "CfgWeapons.hpp" #include "CfgWeapons.hpp"
#include "CfgVehicles.hpp" #include "CfgVehicles.hpp"
#include "ACE_Arsenal_Stats.hpp"

View File

@ -0,0 +1,45 @@
/*
* Author: Alganthe
* Text statement for the weapon muzzle velocity stat
*
* Arguments:
* 0: Not used
* 1: item config path (CONFIG)
*
* Return Value:
* String to display
*
* Public: No
*/
#include "script_component.hpp"
params ["", "_config"];
if (EGVAR(arsenal,currentLeftPanel) == 2002) then {
private _primaryMag = primaryWeaponMagazine EGVAR(arsenal,center);
[primaryWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]]
} else {
private _primaryMag = handgunMagazine EGVAR(arsenal,center);
[handgunWeapon EGVAR(arsenal,center), _primaryMag param [0, ""]]
} params ["_weapon", "_magazine"];
private _initSpeed = getNumber (_config >> "initSpeed");
if (_magazine isEqualTo "") then {
_initSpeed
} else {
private _ammoCfg = (configFile >> "CfgAmmo" >> (getText (configFile >> "CfgMagazines" >> _magazine >> "ammo")));
private _barrelLength = getNumber (_config >> "ACE_barrelLength");
private _muzzleVelocityTable = getArray (_ammoCfg >> "ACE_muzzleVelocities");
private _barrelLengthTable = getArray (_ammoCfg >> "ACE_barrelLengths");
if (_barrelLength != 0 && {count _muzzleVelocityTable > 0} && {count _barrelLengthTable > 0}) then {
private _muzzleVelocity = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift);
format ["%1 m/s (%2 ft/s)", _muzzleVelocity toFixed 0, (_muzzleVelocity * 3.28084) toFixed 0]
} else {
_initSpeed
};
};

View File

@ -0,0 +1 @@
#include "\z\ace\addons\ballistics\script_component.hpp"

View File

@ -2281,5 +2281,24 @@
<Chinese>[ACE] 彈藥補給箱</Chinese> <Chinese>[ACE] 彈藥補給箱</Chinese>
<Chinesesimp>[ACE] 弹药补给箱</Chinesesimp> <Chinesesimp>[ACE] 弹药补给箱</Chinesesimp>
</Key> </Key>
<Key ID="STR_ACE_Ballistics_statBarrelTwist">
<English>Barrel twist</English>
</Key>
<Key ID="STR_ACE_Ballistics_statBarrelLength">
<English>Barrel length</English>
<French>Longueur du canon</French>
</Key>
<Key ID="STR_ACE_Ballistics_statBallisticCoef">
<English>Ballistic coefficient</English>
<French>Coefficient ballistique</French>
</Key>
<Key ID="STR_ACE_Ballistics_statBulletMass">
<English>Bullet mass</English>
<French>Masse d'une balle</French>
</Key>
<Key ID="STR_ACE_Ballistics_statMuzzleVelocity">
<English>Muzzle velocity</English>
<French>Vitesse à la bouche</French>
</Key>
</Package> </Package>
</Project> </Project>

View File

@ -0,0 +1,13 @@
class EGVAR(arsenal,stats) {
class statBase;
class ACE_explosiveRange: statBase {
scope = 2;
priority = 1;
stats[] = {QGVAR(Range)};
displayName= CSTRING(statExploRange);
showText = 1;
textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _exploRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)', _exploRangeStat, (_exploRangeStat / 0.3048) toFixed 1)]);
condition = QUOTE(params [ARR_2('', '_config')]; (getNumber (_config >> QQGVAR(Detonator))) > 0);
tabs[] = {{}, {7}};
};
};

View File

@ -27,6 +27,7 @@ class CfgPatches {
#include "ACE_Triggers.hpp" #include "ACE_Triggers.hpp"
#include "ExplosivesUI.hpp" #include "ExplosivesUI.hpp"
#include "GUI_VirtualAmmo.hpp" #include "GUI_VirtualAmmo.hpp"
#include "ACE_Arsenal_Stats.hpp"
class CfgActions { class CfgActions {
class None; class None;

View File

@ -1019,5 +1019,9 @@
<Chinesesimp>类型: 绊线闪光地雷 - 触发后产生非致命性的强光.&lt;br /&gt;发数: 1&lt;br /&gt;使用于: 地面</Chinesesimp> <Chinesesimp>类型: 绊线闪光地雷 - 触发后产生非致命性的强光.&lt;br /&gt;发数: 1&lt;br /&gt;使用于: 地面</Chinesesimp>
<Chinese>類型: 絆線閃光地雷 - 觸發後產生非致命性的強光.&lt;br /&gt;發數: 1&lt;br /&gt;使用於: 地面</Chinese> <Chinese>類型: 絆線閃光地雷 - 觸發後產生非致命性的強光.&lt;br /&gt;發數: 1&lt;br /&gt;使用於: 地面</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Explosives_statExploRange">
<English>Explosive range</English>
<French>Portée du détonateur</French>
</Key>
</Package> </Package>
</Project> </Project>

View File

@ -0,0 +1,13 @@
class EGVAR(arsenal,stats) {
class statBase;
class ACE_flashlightColor: statBase {
scope = 2;
priority = 1;
stats[] = {"ACE_Flashlight_Colour"};
displayName = CSTRING(statMapLightColor);
showText = 1;
textStatement = QUOTE(getText (_this select 1 >> 'itemInfo' >> 'FlashLight' >> (_this select 0) select 0));
condition = QUOTE(getText (_this select 1 >> 'itemInfo' >> 'FlashLight' >> (_this select 0) select 0) != '');
tabs[] = {{}, {1,7}};
};
};

View File

@ -17,3 +17,4 @@ class CfgPatches {
#include "CfgEventHandlers.hpp" #include "CfgEventHandlers.hpp"
#include "CfgVehicles.hpp" #include "CfgVehicles.hpp"
#include "CfgWeapons.hpp" #include "CfgWeapons.hpp"
#include "ACE_Arsenal_Stats.hpp"

View File

@ -91,5 +91,9 @@
<Chinesesimp>拥有红色滤光片的手电筒。用来照亮地图。</Chinesesimp> <Chinesesimp>拥有红色滤光片的手电筒。用来照亮地图。</Chinesesimp>
<Chinese>擁有紅色濾光片的手電筒。用來照亮地圖。</Chinese> <Chinese>擁有紅色濾光片的手電筒。用來照亮地圖。</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Flashlights_statMapLightColor">
<English>Map light color</English>
<French>Couleur de la lampe sur carte</French>
</Key>
</Package> </Package>
</Project> </Project>

View File

@ -0,0 +1,13 @@
class EGVAR(arsenal,stats) {
class statBase;
class ACE_gReduction: statBase {
scope = 2;
priority = 1;
stats[] = {"ACE_GForceCoef"};
displayName = CSTRING(statGReduction);
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(1, 0)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default));
condition = QUOTE(getNumber (_this select 1 >> (_this select 0) select 0) > 0);
tabs[] = {{3}, {}};
};
};

View File

@ -21,3 +21,4 @@ class CfgPatches {
#include "CfgEventHandlers.hpp" #include "CfgEventHandlers.hpp"
#include "CfgWeapons.hpp" #include "CfgWeapons.hpp"
#include "CfgVehicles.hpp" #include "CfgVehicles.hpp"
#include "ACE_Arsenal_Stats.hpp"

View File

@ -31,5 +31,9 @@
<Chinesesimp>只有战斗机</Chinesesimp> <Chinesesimp>只有战斗机</Chinesesimp>
<Chinese>只有戰鬥機</Chinese> <Chinese>只有戰鬥機</Chinese>
</Key> </Key>
<Key ID="STR_ACE_gforces_statGReduction">
<English>G-force reduction</English>
<French>Reduction des Gs</French>
</Key>
</Package> </Package>
</Project> </Project>

View File

@ -0,0 +1,21 @@
class EGVAR(arsenal,stats) {
class statBase;
class ACE_hearingProtection: statBase {
scope = 2;
priority = 2;
stats[] = {QGVAR(protection)};
displayName= CSTRING(statHearingProtection);
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 1)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default));
tabs[] = {{6}, {}};
};
class ACE_volumeMuffling: statBase {
scope = 2;
priority = 1;
stats[] = {QGVAR(lowerVolume)};
displayName= CSTRING(statHearingLowerVolume);
showBar = 1;
barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_3([ARR_2(0, 1)], [ARR_2(0.01, 1)], false)])] call EFUNC(arsenal,statBarStatement_default))
tabs[] = {{6}, {}};
};
};

View File

@ -20,3 +20,4 @@ class CfgPatches {
#include "CfgWeapons.hpp" #include "CfgWeapons.hpp"
#include "CfgAmmo.hpp" #include "CfgAmmo.hpp"
#include "ACE_Settings.hpp" #include "ACE_Settings.hpp"
#include "ACE_Arsenal_Stats.hpp"

View File

@ -282,6 +282,14 @@
<Chinesesimp>增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。</Chinesesimp> <Chinesesimp>增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。</Chinesesimp>
<Chinese>增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。</Chinese> <Chinese>增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Hearing_statHearingProtection">
<English>Hearing protection</English>
<French>Protection auditive</French>
</Key>
<Key ID="STR_ACE_Hearing_statHearingLowerVolume">
<English>Volume muffling</English>
<French>Étouffement des sons</French>
</Key>
<Key ID="STR_ACE_Hearing_earplugsVolume_DisplayName"> <Key ID="STR_ACE_Hearing_earplugsVolume_DisplayName">
<English>Earplugs Volume</English> <English>Earplugs Volume</English>
</Key> </Key>

View File

@ -0,0 +1,21 @@
class EGVAR(arsenal,stats) {
class statBase;
class ACE_backblastAngle: statBase {
scope = 2;
priority = 2;
stats[] = {QGVAR(angle)};
displayName = CSTRING(statBackblastAngle);
showText = 1;
textStatement = QUOTE(params [ARR_2('_stat', '_config')]; format [ARR_2('%1°', getNumber (_config >> _stat select 0))]);
tabs[] = {{2}, {}};
};
class ACE_backblastRange: statBase {
scope = 2;
priority = 1;
stats[] = {QGVAR(range)};
displayName = CSTRING(statBackblastRange);
showText = 1;
textStatement = QUOTE(params [ARR_2('_stat', '_config')]; private _blastRangeStat = getNumber (_config >> _stat select 0); format [ARR_3('%1m (%2ft)', _blastRangeStat, (_blastRangeStat / 0.3048) toFixed 1)]);
tabs[] = {{2}, {}};
};
};

View File

@ -17,3 +17,4 @@ class CfgPatches {
#include "ACE_Settings.hpp" #include "ACE_Settings.hpp"
#include "CfgEventHandlers.hpp" #include "CfgEventHandlers.hpp"
#include "CfgWeapons.hpp" #include "CfgWeapons.hpp"
#include "ACE_Arsenal_Stats.hpp"

View File

@ -23,5 +23,11 @@
<Chinesesimp>高压影响的范围 [预设: 1]</Chinesesimp> <Chinesesimp>高压影响的范围 [预设: 1]</Chinesesimp>
<Chinese>高壓影響的範圍 [預設: 1]</Chinese> <Chinese>高壓影響的範圍 [預設: 1]</Chinese>
</Key> </Key>
<Key ID="STR_ACE_overpressure_statBackblastRange">
<English>Backblast range</English>
</Key>
<Key ID="STR_ACE_overpressure_statBackblastAngle">
<English>Backblast angle</English>
</Key>
</Package> </Package>
</Project> </Project>