diff --git a/addons/arsenal/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..b9fbfc39c0 --- /dev/null +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -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}, {}}; + }; +}; diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 7596b769d8..e74de9c1aa 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -1,4 +1,5 @@ PREP(addListBoxItem); +PREP(addStat); PREP(addVirtualItems); PREP(buttonCargo); PREP(buttonClearAll); @@ -10,7 +11,10 @@ PREP(buttonLoadoutsLoad); PREP(buttonLoadoutsRename); PREP(buttonLoadoutsSave); PREP(buttonLoadoutsShare); +PREP(buttonStats); +PREP(buttonStatsPage); PREP(clearSearchbar); +PREP(compileStats); PREP(fillLeftPanel); PREP(fillLoadoutsList); PREP(fillRightPanel); @@ -18,6 +22,7 @@ PREP(handleLoadoutsSearchbar); PREP(handleMouse); PREP(handleScrollWheel); PREP(handleSearchbar); +PREP(handleStats); PREP(initBox); PREP(itemInfo); PREP(loadoutsChangeTab); @@ -37,10 +42,16 @@ PREP(open3DEN); PREP(openBox); PREP(portVALoadouts); PREP(removeBox); +PREP(removeStat); PREP(removeVirtualItems); PREP(scanConfig); PREP(showItem); PREP(sortPanel); +PREP(statBarStatement_default); +PREP(statBarStatement_impact); +PREP(statTextStatement_accuracy); +PREP(statTextStatement_mass); +PREP(statTextStatement_rateOfFire); PREP(updateCamPos); PREP(updateRightPanel); PREP(updateUniqueItemsList); diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index d91a73ac96..1919941139 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "defines.hpp" 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(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; diff --git a/addons/arsenal/XEH_preStart.sqf b/addons/arsenal/XEH_preStart.sqf index ed7f4f0345..711d7b3018 100644 --- a/addons/arsenal/XEH_preStart.sqf +++ b/addons/arsenal/XEH_preStart.sqf @@ -3,3 +3,4 @@ #include "XEH_PREP.hpp" call FUNC(scanConfig); +call FUNC(compileStats); diff --git a/addons/arsenal/config.cpp b/addons/arsenal/config.cpp index 0c3000ab3c..9ba31a31f6 100644 --- a/addons/arsenal/config.cpp +++ b/addons/arsenal/config.cpp @@ -39,3 +39,4 @@ class Cfg3DEN { #include "ui\RscAttributes.hpp" #include "CfgEventHandlers.hpp" #include "RscDisplayMain.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index b414484103..42c0e70536 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -104,6 +104,32 @@ #define IDC_buttonMisc 38 #define IDC_buttonRemoveAllSelected 39 #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 IDC_centerBox 3 diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf new file mode 100644 index 0000000000..6b14dcdcd2 --- /dev/null +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -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 diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf index d79ff779d1..da870e0b9f 100644 --- a/addons/arsenal/functions/fnc_buttonHide.sqf +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -48,5 +48,12 @@ private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar); IDC_buttonCurrentMag, IDC_buttonCurrentMag2, IDC_iconBackgroundCurrentMag, - IDC_iconBackgroundCurrentMag2 + IDC_iconBackgroundCurrentMag2, + IDC_statsButton, + IDC_statsPreviousPage, + IDC_statsNextPage, + IDC_statsCurrentPage, + IDC_statsButtonClose ]; + +[QGVAR(statsToggle), [_display, _showToggle]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonStats.sqf b/addons/arsenal/functions/fnc_buttonStats.sqf new file mode 100644 index 0000000000..7fe2d1fbf1 --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonStats.sqf @@ -0,0 +1,31 @@ +/* + * Author: Alganthe + * Toggle the stats control group + * + * Arguments: + * 0: Arsenal display + * 1: Button 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 +]; + diff --git a/addons/arsenal/functions/fnc_buttonStatsPage.sqf b/addons/arsenal/functions/fnc_buttonStatsPage.sqf new file mode 100644 index 0000000000..b1c1cdf7eb --- /dev/null +++ b/addons/arsenal/functions/fnc_buttonStatsPage.sqf @@ -0,0 +1,29 @@ +/* + * Author: Alganthe + * Handles the previous / next page buttons for stats + * + * Arguments: + * 0: Arsenal display + * 1: Previous or next (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; diff --git a/addons/arsenal/functions/fnc_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf new file mode 100644 index 0000000000..05a77d9efd --- /dev/null +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -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]; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index 83a4336ea0..46dbd86e83 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeFillLeftPanel = createProfileScope QFUNC(fillLeftPanel); +#endif + params ["_display", "_control"]; private _ctrlIDC = ctrlIDC _control; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index c62ea3cab8..52d91cf20c 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeFillRightPanel = createProfileScope QFUNC(fillRightPanel); +#endif + params ["_display", "_control"]; private _ctrlIDC = ctrlIDC _control; diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf new file mode 100644 index 0000000000..4105fe092e --- /dev/null +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -0,0 +1,319 @@ +/* + * Author: Alganthe + * Handles the stats control group + * + * Arguments: + * 0: Arsenal display + * 1: Current panel control + * 2: Current panel selection + * 3: Item config entry + * + * 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 + ]; +}; diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf index 9dcfe2ea86..45d5d03164 100644 --- a/addons/arsenal/functions/fnc_itemInfo.sqf +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -16,6 +16,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeItemInfo = createProfileScope QFUNC(itemInfo); +#endif + params ["_display", "_control", "_curSel" ,"_itemCfg"]; private _ctrlInfo = _display displayCtrl IDC_infoBox; @@ -25,6 +29,8 @@ if (isClass _itemCfg) then { _ctrlInfo ctrlSetFade 0; _ctrlInfo ctrlCommit FADE_DELAY; + [QGVAR(displayStats), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; + // Name + author private _ctrlInfoName = _display displayCtrl IDC_infoName; _ctrlInfoName ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == 102)); @@ -70,6 +76,8 @@ if (isClass _itemCfg) then { _ctrlDLCBackground ctrlcommit 0; } else { + [QGVAR(displayStats), [_display, _control, -1, nil]] call CBA_fnc_localEvent; + _ctrlInfo ctrlSetFade 1; _ctrlInfo ctrlCommit FADE_DELAY; }; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index f5194825fd..a456c5e1a3 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -98,6 +98,11 @@ GVAR(currentVoice) = nil; GVAR(currentInsignia) = nil; GVAR(currentAction) = nil; +GVAR(showStats) = nil; +GVAR(statsPagesLeft) = nil; +GVAR(statsPagesRight) = nil; +GVAR(statsInfo) = nil; + GVAR(center) = nil; GVAR(centerNotPlayer) = nil; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index 31777f5ed6..23e03561a8 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -15,6 +15,11 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeArsenal = createProfileScope QFUNC(onArsenalOpen); + profilerTrigger; +#endif + params ["", "_args"]; _args params ["_display"]; @@ -55,6 +60,11 @@ GVAR(currentInsignia) = GVAR(center) param [0, objNull, [objNull]] getVariable [ GVAR(currentAction) = "Stand"; 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 for "_index" from 0 to 10 do { switch (_index) do { @@ -199,6 +209,20 @@ _mouseBlockCtrl ctrlEnable false; 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 { private _importButtonCtrl = _display displayCtrl IDC_buttonImport; _importButtonCtrl ctrlEnable false; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 5c4d49b5d1..b70f7b00e6 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeOnSelChangedLeft = createProfileScope QFUNC(onSelChangedLeft); +#endif + params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index 7a565cd14d..ce40ef87f6 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeOnSelChangedRight = createProfileScope QFUNC(onSelChangedRight); +#endif + params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; diff --git a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf index 29c66a79f9..531c0817c8 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeOnSelChangedRightLNB = createProfileScope QFUNC(onSelChangedRightListnBox); +#endif + params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; diff --git a/addons/arsenal/functions/fnc_removeStat.sqf b/addons/arsenal/functions/fnc_removeStat.sqf new file mode 100644 index 0000000000..654949753f --- /dev/null +++ b/addons/arsenal/functions/fnc_removeStat.sqf @@ -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; diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index 478ae4218d..fddfbe1a3a 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -13,6 +13,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeShowItem = createProfileScope QFUNC(showItem); +#endif + if (GVAR(centerNotPlayer)) exitWith {}; private _nextAction = switch (GVAR(currentLeftPanel)) do { diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index c8bf02777f..a81b31bd82 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeSortPanel = createProfileScope QFUNC(sortPanel); +#endif + params ["_control", "_mode"]; private _display = ctrlParent _control; diff --git a/addons/arsenal/functions/fnc_statBarStatement_default.sqf b/addons/arsenal/functions/fnc_statBarStatement_default.sqf new file mode 100644 index 0000000000..d31529b55b --- /dev/null +++ b/addons/arsenal/functions/fnc_statBarStatement_default.sqf @@ -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] diff --git a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf new file mode 100644 index 0000000000..d979a178a0 --- /dev/null +++ b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf @@ -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) diff --git a/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf new file mode 100644 index 0000000000..0f69236bb3 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf @@ -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]; diff --git a/addons/arsenal/functions/fnc_statTextStatement_mass.sqf b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf new file mode 100644 index 0000000000..9be8c1c7d1 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf @@ -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] diff --git a/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf new file mode 100644 index 0000000000..a34a2f7d7b --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf @@ -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))] diff --git a/addons/arsenal/functions/fnc_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf index 41c7c68483..42a0275fbb 100644 --- a/addons/arsenal/functions/fnc_updateRightPanel.sqf +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -14,6 +14,10 @@ #include "script_component.hpp" #include "..\defines.hpp" +#ifdef ENABLE_PERF_PROFILING + private _scopeUpdateRightPanel = createProfileScope QFUNC(updateRightPanel); +#endif + params ["_control", "_maxLoad"]; private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index e7946b8b10..d5d0923511 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -60,13 +60,13 @@ private _fnc_weaponCheck = { if (isClass (_magCfg >> _mag)) then { if !(_mag in (GVAR(virtualItems) select 2)) then { - _unavailableItemsList pushBackUnique _item; + _unavailableItemsList pushBackUnique _mag; _dataPath set [_forEachIndex, []]; _unavailableItemsAmount = _unavailableItemsAmount + 1; }; } else { - _nullItemsList pushBackUnique _item; + _nullItemsList pushBackUnique _mag; _dataPath set [_forEachIndex, []]; _nullItemsAmount = _nullItemsAmount + 1; }; diff --git a/addons/arsenal/script_component.hpp b/addons/arsenal/script_component.hpp index 2eb9c3f170..791b9663dc 100644 --- a/addons/arsenal/script_component.hpp +++ b/addons/arsenal/script_component.hpp @@ -5,6 +5,7 @@ // #define DEBUG_MODE_FULL // #define DISABLE_COMPILE_CACHE // #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 #define DEBUG_MODE_FULL diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index f22d38a8c4..518d2bf9d8 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -682,6 +682,14 @@ 匯入當前/預設的裝備 汇入当前/预设的装备 + + Potassium levels + Taux de potassium + + + Page + Page + Enable the faces / voices / insignias tabs Activer les onglets faces / voix / insignes diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index e52929a58a..793c5fede2 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -42,7 +42,7 @@ class GVAR(display) { idc = IDC_arrowMinus; text = "-"; 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; enable = 0; x = 0.5; @@ -53,7 +53,7 @@ class GVAR(display) { }; class ArrowRight: ArrowLeft { 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="+"; }; class blockLeftFrame: RscFrame { @@ -177,7 +177,7 @@ class GVAR(display) { sizeEx = QUOTE(5 * GRID_H); shortcuts[] = {"0x0E"}; tooltip = CSTRING(buttonHideTooltip); - onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonHide)); + onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonHide)); }; class buttonLoadouts: buttonHide { idc = IDC_buttonLoadouts; @@ -191,14 +191,14 @@ class GVAR(display) { x = QUOTE(3 * WIDTH_GAP + 2 * WIDTH_SINGLE); text = CSTRING(buttonExportText); tooltip = CSTRING(buttonExportTooltip); - onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonExport)); + onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonExport)); }; class buttonImport: buttonHide { idc = IDC_buttonImport; x = QUOTE(4 * WIDTH_GAP + 3 * WIDTH_SINGLE); text = CSTRING(buttonImportText); tooltip = CSTRING(buttonImportTooltip); - onButtonClick = QUOTE([ctrlparent (_this select 0)] call FUNC(buttonImport)); + onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonImport)); }; class buttonClose: ctrlButtonOK { idc = IDC_menuBarClose; @@ -209,7 +209,7 @@ class GVAR(display) { h = QUOTE(7 * GRID_H); text = CSTRING(buttonCloseText); 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 { idc = IDC_mouseBlock; style = 16; @@ -376,7 +564,7 @@ class GVAR(display) { idc = IDC_leftSearchbarButton; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; 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); y = QUOTE(safezoneY + 1.8 * GRID_H); w = QUOTE(6 * GRID_W); @@ -390,7 +578,7 @@ class GVAR(display) { }; class rightSearchbarButton: leftSearchbarButton { 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); }; class tabLeft: RscControlsGroupNoScrollbars { @@ -414,7 +602,7 @@ class GVAR(display) { idc = IDC_buttonPrimaryWeapon; text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa"; 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}; x = QUOTE(0 * GRID_W); y = QUOTE(0 * GRID_H); @@ -607,7 +795,7 @@ class GVAR(display) { idc = IDC_buttonOptic; tooltip="$STR_A3_RscDisplayArsenal_tab_ItemOptic"; 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}; x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); @@ -776,7 +964,7 @@ class GVAR(loadoutsDisplay) { onSetFocus = QUOTE(GVAR(loadoutsPanelFocus) = true); onKillFocus = QUOTE(GVAR(loadoutsPanelFocus) = false); 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); y = QUOTE(5 * GRID_H); w = QUOTE(160 * GRID_W); @@ -814,7 +1002,7 @@ class GVAR(loadoutsDisplay) { idc = -1; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; 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); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(5 * GRID_W); @@ -829,7 +1017,7 @@ class GVAR(loadoutsDisplay) { text= CSTRING(buttonSaveText); tooltip= CSTRING(buttonSaveTooltip); 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}; }; class buttonRename: buttonSave { @@ -837,21 +1025,21 @@ class GVAR(loadoutsDisplay) { x = QUOTE(32.5 * GRID_W); text= CSTRING(buttonRenameText); 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 { idc = IDC_buttonLoad; x = QUOTE(65 * GRID_W); text= CSTRING(buttonLoadText); 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 { idc = IDC_buttonShare; x = QUOTE(97.5 * GRID_W); text= CSTRING(buttonSharePrivateText); 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 { idc = IDC_buttonDelete; @@ -859,11 +1047,10 @@ class GVAR(loadoutsDisplay) { text= CSTRING(buttonDeleteText); tooltip= CSTRING(buttonDeleteTooltip); 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 { idc = -1; x = QUOTE(safezoneW + safezoneX - 32 * GRID_W); @@ -874,7 +1061,7 @@ class GVAR(loadoutsDisplay) { text= CSTRING(buttonCloseText); shortcuts[]= {"0x01"}; tooltip= ""; - onButtonClick = QUOTE(ctrlparent (_this select 0) closeDisplay 2); + onButtonClick = QUOTE(ctrlParent (_this select 0) closeDisplay 2); }; class buttonBar: ctrlControlsGroupNoScrollbars { idc = -1; @@ -901,7 +1088,7 @@ class GVAR(loadoutsDisplay) { sizeEx = QUOTE(5 * GRID_H); text= CSTRING(tabMyLoadoutsText); 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 { idc = IDC_buttonDefaultLoadoutsBackground; diff --git a/addons/ballistics/ACE_Arsenal_Stats.hpp b/addons/ballistics/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..4cf9872b7a --- /dev/null +++ b/addons/ballistics/ACE_Arsenal_Stats.hpp @@ -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}, {}}; + }; +}; diff --git a/addons/ballistics/CfgEventHandlers.hpp b/addons/ballistics/CfgEventHandlers.hpp new file mode 100644 index 0000000000..93e3311cf2 --- /dev/null +++ b/addons/ballistics/CfgEventHandlers.hpp @@ -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)); + }; +}; diff --git a/addons/ballistics/XEH_PREP.hpp b/addons/ballistics/XEH_PREP.hpp new file mode 100644 index 0000000000..812a51e6f6 --- /dev/null +++ b/addons/ballistics/XEH_PREP.hpp @@ -0,0 +1 @@ +PREP(statTextStatement_weaponMuzzleVelocity); diff --git a/addons/ballistics/XEH_preInit.sqf b/addons/ballistics/XEH_preInit.sqf new file mode 100644 index 0000000000..63f3d7fe7e --- /dev/null +++ b/addons/ballistics/XEH_preInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; diff --git a/addons/ballistics/XEH_preStart.sqf b/addons/ballistics/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/ballistics/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/ballistics/config.cpp b/addons/ballistics/config.cpp index 7f63a36dd2..0dc8289901 100644 --- a/addons/ballistics/config.cpp +++ b/addons/ballistics/config.cpp @@ -14,7 +14,9 @@ class CfgPatches { }; }; +#include "CfgEventHandlers.hpp" #include "CfgAmmo.hpp" #include "CfgMagazines.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf new file mode 100644 index 0000000000..1fcc75d405 --- /dev/null +++ b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf @@ -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 + }; +}; diff --git a/addons/ballistics/functions/script_component.hpp b/addons/ballistics/functions/script_component.hpp new file mode 100644 index 0000000000..a257e3d384 --- /dev/null +++ b/addons/ballistics/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\ballistics\script_component.hpp" diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index d4ff60c811..b23273ac23 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -2281,5 +2281,24 @@ [ACE] 彈藥補給箱 [ACE] 弹药补给箱 + + Barrel twist + + + Barrel length + Longueur du canon + + + Ballistic coefficient + Coefficient ballistique + + + Bullet mass + Masse d'une balle + + + Muzzle velocity + Vitesse à la bouche + diff --git a/addons/explosives/ACE_Arsenal_Stats.hpp b/addons/explosives/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..61534b0f9d --- /dev/null +++ b/addons/explosives/ACE_Arsenal_Stats.hpp @@ -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}}; + }; +}; diff --git a/addons/explosives/config.cpp b/addons/explosives/config.cpp index 71952c2eec..57bcdfd204 100644 --- a/addons/explosives/config.cpp +++ b/addons/explosives/config.cpp @@ -27,6 +27,7 @@ class CfgPatches { #include "ACE_Triggers.hpp" #include "ExplosivesUI.hpp" #include "GUI_VirtualAmmo.hpp" +#include "ACE_Arsenal_Stats.hpp" class CfgActions { class None; diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 2ca36bcdc1..3882733567 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -1019,5 +1019,9 @@ 类型: 绊线闪光地雷 - 触发后产生非致命性的强光.<br />发数: 1<br />使用于: 地面 類型: 絆線閃光地雷 - 觸發後產生非致命性的強光.<br />發數: 1<br />使用於: 地面 + + Explosive range + Portée du détonateur + diff --git a/addons/flashlights/ACE_Arsenal_Stats.hpp b/addons/flashlights/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..7a5e7ea39a --- /dev/null +++ b/addons/flashlights/ACE_Arsenal_Stats.hpp @@ -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}}; + }; +}; diff --git a/addons/flashlights/config.cpp b/addons/flashlights/config.cpp index 734a47db86..eefeb782f1 100644 --- a/addons/flashlights/config.cpp +++ b/addons/flashlights/config.cpp @@ -17,3 +17,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index 08e291a2b6..a4749ef27d 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -91,5 +91,9 @@ 拥有红色滤光片的手电筒。用来照亮地图。 擁有紅色濾光片的手電筒。用來照亮地圖。 + + Map light color + Couleur de la lampe sur carte + diff --git a/addons/gforces/ACE_Arsenal_Stats.hpp b/addons/gforces/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..4148ba5fe2 --- /dev/null +++ b/addons/gforces/ACE_Arsenal_Stats.hpp @@ -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}, {}}; + }; +}; diff --git a/addons/gforces/config.cpp b/addons/gforces/config.cpp index e05f582d08..da9e6a2328 100644 --- a/addons/gforces/config.cpp +++ b/addons/gforces/config.cpp @@ -21,3 +21,4 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index adf7fb114d..d0ae62de3d 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -31,5 +31,9 @@ 只有战斗机 只有戰鬥機 + + G-force reduction + Reduction des Gs + diff --git a/addons/hearing/ACE_Arsenal_Stats.hpp b/addons/hearing/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..481ab62327 --- /dev/null +++ b/addons/hearing/ACE_Arsenal_Stats.hpp @@ -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}, {}}; + }; +}; diff --git a/addons/hearing/config.cpp b/addons/hearing/config.cpp index e562227047..a1cc956d89 100644 --- a/addons/hearing/config.cpp +++ b/addons/hearing/config.cpp @@ -20,3 +20,4 @@ class CfgPatches { #include "CfgWeapons.hpp" #include "CfgAmmo.hpp" #include "ACE_Settings.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 1d5a2830b0..ef074b12cc 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -282,6 +282,14 @@ 增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。 增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。 + + Hearing protection + Protection auditive + + + Volume muffling + Étouffement des sons + Earplugs Volume diff --git a/addons/overpressure/ACE_Arsenal_Stats.hpp b/addons/overpressure/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..906c50e8fb --- /dev/null +++ b/addons/overpressure/ACE_Arsenal_Stats.hpp @@ -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}, {}}; + }; +}; diff --git a/addons/overpressure/config.cpp b/addons/overpressure/config.cpp index d99cbb1cc7..3815cc831f 100644 --- a/addons/overpressure/config.cpp +++ b/addons/overpressure/config.cpp @@ -17,3 +17,4 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" +#include "ACE_Arsenal_Stats.hpp" diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index 9d909f918e..e04d8d43bd 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -23,5 +23,11 @@ 高压影响的范围 [预设: 1] 高壓影響的範圍 [預設: 1] + + Backblast range + + + Backblast angle +