From d72555ab0c305efb5c8e819d0945bcebfcc4b681 Mon Sep 17 00:00:00 2001 From: Brett Date: Tue, 18 Aug 2020 11:43:35 -0600 Subject: [PATCH] Arsenal - Add Sorting Algorithms (#7719) * support per tab sorting, and external algorithms * improved sub sorting * improve alphabetical search * update mod sorting * sort by accuracy * sort right panel * more sorts * sort right tab * fix empty * stringtables * Apply suggestions from code review Co-authored-by: mharis001 <34453221+mharis001@users.noreply.github.com> * more suggestions * suggestions * remember last sort * Fix missing throw and put names * bad copy paste in stringtable * Update addons/arsenal/functions/fnc_sortPanel.sqf Co-authored-by: PabstMirror Co-authored-by: mharis001 <34453221+mharis001@users.noreply.github.com> Co-authored-by: PabstMirror --- addons/arsenal/ACE_Arsenal_Sorts.hpp | 64 +++++++ addons/arsenal/XEH_PREP.hpp | 9 + addons/arsenal/XEH_postInit.sqf | 2 + addons/arsenal/XEH_preInit.sqf | 3 +- addons/arsenal/config.cpp | 3 +- addons/arsenal/defines.hpp | 3 - .../arsenal/functions/fnc_addListBoxItem.sqf | 8 +- addons/arsenal/functions/fnc_addSort.sqf | 70 +++++++ addons/arsenal/functions/fnc_addStat.sqf | 4 +- addons/arsenal/functions/fnc_compileSorts.sqf | 82 ++++++++ .../arsenal/functions/fnc_fillLeftPanel.sqf | 13 +- .../arsenal/functions/fnc_fillRightPanel.sqf | 25 +-- addons/arsenal/functions/fnc_fillSort.sqf | 99 ++++++++++ addons/arsenal/functions/fnc_sortPanel.sqf | 178 +++++++++++++----- .../functions/fnc_sortStatement_accuracy.sqf | 34 ++++ .../functions/fnc_sortStatement_magCount.sqf | 17 ++ .../functions/fnc_sortStatement_mass.sqf | 27 +++ .../functions/fnc_sortStatement_mod.sqf | 26 +++ .../fnc_sortStatement_rateOfFire.sqf | 26 +++ .../functions/fnc_sortStatement_scopeMag.sqf | 24 +++ addons/arsenal/stringtable.xml | 20 ++ addons/arsenal/ui/RscAttributes.hpp | 22 --- 22 files changed, 644 insertions(+), 115 deletions(-) create mode 100644 addons/arsenal/ACE_Arsenal_Sorts.hpp create mode 100644 addons/arsenal/functions/fnc_addSort.sqf create mode 100644 addons/arsenal/functions/fnc_compileSorts.sqf create mode 100644 addons/arsenal/functions/fnc_fillSort.sqf create mode 100644 addons/arsenal/functions/fnc_sortStatement_accuracy.sqf create mode 100644 addons/arsenal/functions/fnc_sortStatement_magCount.sqf create mode 100644 addons/arsenal/functions/fnc_sortStatement_mass.sqf create mode 100644 addons/arsenal/functions/fnc_sortStatement_mod.sqf create mode 100644 addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf create mode 100644 addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf diff --git a/addons/arsenal/ACE_Arsenal_Sorts.hpp b/addons/arsenal/ACE_Arsenal_Sorts.hpp new file mode 100644 index 0000000000..2ed1aa92ee --- /dev/null +++ b/addons/arsenal/ACE_Arsenal_Sorts.hpp @@ -0,0 +1,64 @@ +class GVAR(sorts) { + class sortBase { + scope = 1; + displayName = ""; + tabs[] = {{}, {}}; + statement = ""; + }; + + class ACE_alphabetically: sortBase { + scope = 2; + displayName = "$STR_a3_rscdisplayarsenal_sort_alphabet"; + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE({}); + }; + + class ACE_mod: sortBase { + scope = 2; + displayName = "$STR_a3_rscdisplayarsenal_sort_mod"; + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE(_this call FUNC(sortStatement_mod)); + }; + + class ACE_mass: sortBase { + scope = 2; + displayName = CSTRING(sortByWeightText); + tabs[] = {{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, {0,1,2,3,4,5,6,7}}; + statement = QUOTE(_this call FUNC(sortStatement_mass)); + }; + + class ACE_load: sortBase { + scope = 2; + displayName = CSTRING(sortByLoadText); + tabs[] = {{3,4,5}, {}}; + statement = QUOTE(getContainerMaxLoad configName _this); + }; + + class ACE_accuracy: sortBase { + scope = 2; + displayName = CSTRING(sortByAccuracyText); + tabs[] = {{0,1,2}, {}}; + statement = QUOTE(_this call FUNC(sortStatement_accuracy)); + }; + + class ACE_rateOfFire: sortBase { + scope = 2; + displayName = CSTRING(sortByRateOfFireText); + tabs[] = {{0,1,2}, {}}; + statement = QUOTE(_this call FUNC(sortStatement_rateOfFire)); + }; + + class ACE_scopeMag: sortBase { + scope = 2; + displayName = CSTRING(sortByMagnificationText); + tabs[] = {{}, {0}}; + statement = QUOTE(_this call FUNC(sortStatement_scopeMag)); + }; + + class ACE_magCount: sortBase { + scope = 2; + displayName = CSTRING(sortByMagCountText); + tabs[] = {{}, {4}}; + statement = QUOTE(_this call FUNC(sortStatement_magCount)); + }; +}; diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 30117d5d81..4879e6d7a1 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -1,5 +1,6 @@ PREP(addDefaultLoadout); PREP(addListBoxItem); +PREP(addSort); PREP(addRightPanelButton); PREP(addStat); PREP(addVirtualItems); @@ -27,10 +28,12 @@ PREP(buttonLoadoutsShare); PREP(buttonStats); PREP(buttonStatsPage); PREP(clearSearchbar); +PREP(compileSorts); PREP(compileStats); PREP(fillLeftPanel); PREP(fillLoadoutsList); PREP(fillRightPanel); +PREP(fillSort); PREP(handleLoadoutsSearchbar); PREP(handleMouse); PREP(handleScrollWheel); @@ -60,6 +63,12 @@ PREP(removeVirtualItems); PREP(scanConfig); PREP(showItem); PREP(sortPanel); +PREP(sortStatement_accuracy); +PREP(sortStatement_magCount); +PREP(sortStatement_mass); +PREP(sortStatement_mod); +PREP(sortStatement_rateOfFire); +PREP(sortStatement_scopeMag); PREP(statBarStatement_accuracy); PREP(statBarStatement_default); PREP(statBarStatement_impact); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index 5623439cda..9b92f8ee51 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -5,6 +5,8 @@ GVAR(EH_ID) = 0; GVAR(lastSearchTextLeft) = ""; GVAR(lastSearchTextRight) = ""; GVAR(lastSearchTextLoadouts) = ""; +GVAR(lastSortLeft) = ""; +GVAR(lastSortRight) = ""; [QGVAR(initBox), {_this call FUNC(initBox)}] call CBA_fnc_addEventHandler; [QGVAR(removeBox), {_this call FUNC(removeBox)}] call CBA_fnc_addEventHandler; diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 1e37d369d7..1aebf5040f 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -8,8 +8,6 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; // Arsenal -GVAR(modList) = ["", "curator", "kart", "heli", "mark", "expansion", "expansionpremium"]; - [QGVAR(camInverted), "CHECKBOX", localize LSTRING(invertCameraSetting), localize LSTRING(settingCategory), false] call CBA_Settings_fnc_init; [QGVAR(enableModIcons), "CHECKBOX", [LSTRING(modIconsSetting), LSTRING(modIconsTooltip)], localize LSTRING(settingCategory), true] call CBA_Settings_fnc_init; [QGVAR(fontHeight), "SLIDER", [LSTRING(fontHeightSetting), LSTRING(fontHeightTooltip)], localize LSTRING(settingCategory), [1, 10, 4.5, 1]] call CBA_Settings_fnc_init; @@ -58,6 +56,7 @@ GVAR(modList) = ["", "curator", "kart", "heli", "mark", "expansion", "expansionp }] call CBA_fnc_addEventHandler; call FUNC(compileStats); +call FUNC(compileSorts); [QUOTE(ADDON), {!isNil QGVAR(camera)}] call CBA_fnc_registerFeatureCamera; diff --git a/addons/arsenal/config.cpp b/addons/arsenal/config.cpp index 0bc1ba37d6..cd526e3494 100644 --- a/addons/arsenal/config.cpp +++ b/addons/arsenal/config.cpp @@ -8,7 +8,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); - authors[] = {"alganthe", "mharis001"}; + authors[] = {"alganthe", "mharis001", "SynixeBrett"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; @@ -20,4 +20,5 @@ class CfgPatches { #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" #include "RscDisplayMain.hpp" +#include "ACE_Arsenal_Sorts.hpp" #include "ACE_Arsenal_Stats.hpp" diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 7f4ff6952b..7e38023b5c 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -198,9 +198,6 @@ private _dlcName = _this call GETDLC;\ if (_dlcName != "") then {\ _ctrlPanel lbsetpictureright [_lbAdd,(modParams [_dlcName,["logo"]]) param [0,""]];\ - _modID = GVAR(modList) find _dlcName;\ - if (_modID < 0) then {_modID = GVAR(modList) pushback _dlcName;};\ - _ctrlPanel lbsetvalue [_lbAdd,_modID];\ };\ }; diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index 8a3fb1491f..35cde798ee 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -20,7 +20,7 @@ private _cacheNamespace = _ctrlPanel; //For better readability. private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; -//_cachedItemInfo == [_displayName, _itemPicture, _modPicture, _modID] +//_cachedItemInfo == [_displayName, _itemPicture, _modPicture] if (_cachedItemInfo isEqualTo []) then {//Not in cache. So get info and put into cache. private _configPath = configFile >> _configCategory >> _className; @@ -41,9 +41,6 @@ if (_cachedItemInfo isEqualTo []) then {//Not in cache. So get info and put into if (_dlcName != "") then { _cachedItemInfo set [2, (modParams [_dlcName,["logo"]]) param [0,""]];//mod picture - _modID = GVAR(modList) find _dlcName; - if (_modID < 0) then {_modID = GVAR(modList) pushback _dlcName;};//We keep a ordered list of all mods for sorting later. - _cachedItemInfo set [3, _modID];//mod ID } else { _cachedItemInfo set [2, ""];//mod picture _cachedItemInfo set [3, 0];//mod ID @@ -51,12 +48,11 @@ if (_cachedItemInfo isEqualTo []) then {//Not in cache. So get info and put into _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; }; -_cachedItemInfo params ["_displayName", "_itemPicture", "_modPicture", "_modID"]; +_cachedItemInfo params ["_displayName", "_itemPicture", "_modPicture"]; private _lbAdd = _ctrlPanel lbAdd _displayName; _ctrlPanel lbSetData [_lbAdd, _className]; _ctrlPanel lbSetPicture [_lbAdd, _itemPicture]; _ctrlPanel lbSetPictureRight [_lbAdd,["",_modPicture] select (GVAR(enableModIcons))]; -_ctrlPanel lbSetValue [_lbAdd,_modID]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; diff --git a/addons/arsenal/functions/fnc_addSort.sqf b/addons/arsenal/functions/fnc_addSort.sqf new file mode 100644 index 0000000000..6faa2ba51c --- /dev/null +++ b/addons/arsenal/functions/fnc_addSort.sqf @@ -0,0 +1,70 @@ +#include "script_component.hpp" +/* + * Author: SynixeBrett + * Add a custom sorting method. + * + * Arguments: + * 0: Tabs to add stat to + * 0: Left Tab Indexes + * 1: Right Tab Indexes + * 1: Sort Class (a unique string for each algorithm) + * 2: Display Name + * 3: Algorithm + * + * Return Value: + * 0: Array of IDs (ARRAY of STRINGS) + * + * Example: + * [[[0, 1]], "fireRateSort", "Sort by fire rate", { + * params ["_itemCfg"]; + * private _fireModes = getArray (_itemCfg >> "modes"); + * private _fireRate = []; + * + * { + * _fireRate pushBackUnique (getNumber (_itemCfg >> _x >> "reloadTime")); + * } foreach _fireModes; + * + * _fireRate sort true; + * _fireRate param [0, 0] + * }] call ACE_arsenal_fnc_addSort; + * + * Public: Yes + */ + +params [ + ["_tabs", [[], []], [[]], 2], + ["_class", "", [""]], + ["_displayName", "", [""]], + ["_statement", {}, [{}]] +]; + +_tabs params [ + ["_leftTabs", [], [[]]], + ["_rightTabs", [], [[]]] +]; + +call FUNC(compileSorts); + +private _returnArray = []; + +private _fnc_addToTabs = { + params ["_tabsList", "_tabsToAddTo", "_sideString"]; + { + private _arrayToSave = +_finalArray; + _arrayToSave set [0, [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; + _returnArray pushBack (_arrayToSave select 0); + (_tabsList select _x) pushBack _arrayToSave; + } forEach _tabsToAddTo; +}; + +_finalArray = ["", _displayName, _statement]; + +if !(_leftTabs isEqualTo []) then { + [GVAR(sortListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; +}; + +if !(_rightTabs isEqualTo []) then { + [GVAR(sortListRightPanel), _rightTabs, "R", 1] call _fnc_addToTabs; +}; + +_returnArray diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf index 61e361fd0f..ac13e97699 100644 --- a/addons/arsenal/functions/fnc_addStat.sqf +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Tabs to add the stat to (ARRAY of ARRAYS) - * 0.1: Left tab indexes (ARRAY of NUMBERS) + * 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) @@ -14,7 +14,7 @@ * 4.1 Show bar (BOOL) * 4.2 Show text (BOOL) * 5: Array of statements (ARRAY of ARRAYS) - * 5.1: Bar code (CODE) + * 5.1 Bar code (CODE) * 5.2 Text code (CODE) * 5.3 Condition code (CODE) * 6: Priority (NUMBER) (Optional) diff --git a/addons/arsenal/functions/fnc_compileSorts.sqf b/addons/arsenal/functions/fnc_compileSorts.sqf new file mode 100644 index 0000000000..762ff14a3d --- /dev/null +++ b/addons/arsenal/functions/fnc_compileSorts.sqf @@ -0,0 +1,82 @@ +#include "script_component.hpp" +/* + * Author: SynixeBrett + * Create the internal stats arrays when needed for the first time + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +if (!isNil QGVAR(sortListLeftPanel)) exitWith {}; + +private _fnc_addToTabs = { + params ["_tabsList", "_tabsToAddTo", "_sideString"]; + { + private _arrayToSave = +_finalArray; + _arrayToSave set [0, [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; + (_tabsList select _x) pushBack _arrayToSave; + } forEach _tabsToAddTo; +}; + +private _sortListLeftPanel = [ + [], // 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 _sortListRightPanel = [ + [], // 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(sorts)); + +{ + private _finalArray = []; + + private _class = configName _x; + private _displayName = getText (_x >> "displayName"); + private _statement = getText (_x >> "statement"); + (getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"]; + + if (_statement != "") then { + _statement = compile _statement; + }; + + _finalArray = ["", _displayName, _statement]; + + if !(_leftTabsList isEqualTo []) then { + [_sortListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs; + }; + + if !(_rightTabsList isEqualTo []) then { + [_sortListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; + }; +} foreach _configEntries; + +missionNamespace setVariable [QGVAR(sortListLeftPanel), _sortListLeftPanel]; +missionNamespace setVariable [QGVAR(sortListRightPanel), _sortListRightPanel]; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index a662b91eb1..c8d3f97734 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -37,6 +37,10 @@ _ctrlPanel ctrlCommit FADE_DELAY; _ctrlPanel lbSetCurSel -1; +// Fill sort options +private _sortLeftCtrl = _display displayCtrl IDC_sortLeftTab; +[_display, _control, _sortLeftCtrl] call FUNC(fillSort); + // Handle icons and filling switch true do { case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]) : { @@ -138,8 +142,8 @@ switch true do { { { if ( - getnumber (_x >> "disabled") == 0 && - {getText (_x >> "head") != ""} && + getnumber (_x >> "disabled") == 0 && + {getText (_x >> "head") != ""} && {configName _x != "Default"} ) then { private _configName = configName _x; @@ -162,7 +166,7 @@ switch true do { { ["CfgUnitInsignia", configName _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); } foreach ("true" configClasses (configFile >> "CfgUnitInsignia")); - + { private _displayName = getText (_x >> "displayName"); private _className = configName _x; @@ -187,8 +191,7 @@ GVAR(currentLeftPanel) = _ctrlIDC; [QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent; // Sort -private _sortLeftCtrl = _display displayCtrl IDC_sortLeftTab; -[_sortLeftCtrl, _sortLeftCtrl lbValue (lbCurSel _sortLeftCtrl)] call FUNC(sortPanel); +[_sortLeftCtrl] call FUNC(sortPanel); //Select current item private _itemsToCheck = ((GVAR(currentItems) select [0,15]) + [GVAR(currentFace), GVAR(currentVoice), GVAR(currentInsignia)]) apply {tolower _x}; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index 8cd64c73f2..ae675ffcdf 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -351,30 +351,9 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Sorting private _sortRightCtrl = _display displayCtrl IDC_sortRightTab; -private _sortRightCurSel = lbCurSel _sortRightCtrl; +[_display, _control, _sortRightCtrl] call FUNC(fillSort); -if (lbSize _sortRightCtrl == 3) then { - _sortRightCtrl lbDelete 2; -}; - -if (_leftPanelState) then { - _sortRightCtrl lbDelete 1; - _sortRightCtrl lbAdd (localize "STR_a3_rscdisplayarsenal_sort_mod"); - _sortRightCtrl lbSetValue [1, 1]; - - _sortRightCtrl lbSetCurSel ([0, _sortRightCurSel] select (_sortRightCurSel != 2)); -} else { - _sortRightCtrl lbDelete 1; - _sortRightCtrl lbAdd localize LSTRING(sortByWeightText); - _sortRightCtrl lbSetValue [1, 1]; - - _sortRightCtrl lbAdd localize LSTRING(sortByAmountText); - _sortRightCtrl lbSetValue [2, 2]; - - _sortRightCtrl lbSetCurSel _sortRightCurSel; -}; - -[_sortRightCtrl, _sortRightCtrl lbValue (lbCurSel _sortRightCtrl)] call FUNC(sortPanel); +[_sortRightCtrl] call FUNC(sortPanel); // Select current data if not in a container if !(_itemsToCheck isEqualTo []) then { diff --git a/addons/arsenal/functions/fnc_fillSort.sqf b/addons/arsenal/functions/fnc_fillSort.sqf new file mode 100644 index 0000000000..065296ebbd --- /dev/null +++ b/addons/arsenal/functions/fnc_fillSort.sqf @@ -0,0 +1,99 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: Alganthe, SynixeBrett + * Fill right panel. + * + * Arguments: + * 0: Arsenal display + * 1: Tab control + * 2: Sort control + * + * Return Value: + * None + * + * Public: No +*/ + +params ["_display", "_control", "_sortCtrl"]; + +lbClear _sortCtrl; + +private _right = false; +private _rightSort = ctrlIDC _sortCtrl == 17; + +private _sorts = if (_rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform ,IDC_buttonVest, IDC_buttonBackpack]}) then { + _right = true; + GVAR(sortListRightPanel) select ( + switch (GVAR(currentRightPanel)) do { + case IDC_buttonOptic: { 0 }; + case IDC_buttonItemAcc: { 1 }; + case IDC_buttonMuzzle: { 2 }; + case IDC_buttonBipod: { 3 }; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: { 4 }; + case IDC_buttonThrow: { 5 }; + case IDC_buttonPut: { 6 }; + case IDC_buttonMisc: { 7 }; + } + ) +} else { + private _sidc = ctrlIDC _sortCtrl; + private _idc = ctrlIDC _control; + switch true do { + case (_sidc == 17): { // Right panel weapon attachment + GVAR(sortListRightPanel) select ( + switch (_idc) do { + case IDC_buttonOptic: { 0 }; + case IDC_buttonItemAcc: { 1 }; + case IDC_buttonMuzzle: { 2 }; + case IDC_buttonBipod: { 3 }; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: { 4 }; + case IDC_buttonThrow: { 5 }; + case IDC_buttonPut: { 6 }; + case IDC_buttonMisc: { 7 }; + } + ) + }; + case ([IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsigna] find _idc > -1): { + [] + }; + default { + GVAR(sortListLeftPanel) select ([ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch + ] find _idc) + }; + } +}; + +private _lastSort = [GVAR(lastSortLeft), GVAR(lastSortRight)] select _rightSort; +private _sortIndex = 0; + +{ + if (_x isEqualTo []) exitWith {}; + _sortCtrl lbAdd (_x select 1); + if ((_x select 1) isEqualTo _lastSort) then { + _sortIndex = _forEachIndex; + }; +} forEach _sorts; + +_sortCtrl lbSetCurSel _sortIndex; diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index 5d3a2af017..8169cf7889 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -1,12 +1,11 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, Dedmen + * Author: Alganthe, Dedmen, SynixeBrett * Sort arsenal panel. * * Arguments: - * 0: Panel's control to sort - * 1: Sorting mode + * 0: Sort control * * Return Value: * None @@ -14,60 +13,137 @@ * Public: No */ -params ["_control", "_mode"]; +params ["_sortControl"]; -private _display = ctrlParent _control; -private ["_panel", "_curSel", "_selected"]; +private _display = ctrlParent _sortControl; -// Right panel -if (ctrlIDC _control == 17 && {GVAR(currentLeftPanel) in [IDC_buttonUniform ,IDC_buttonVest, IDC_buttonBackpack]}) then { - _panel = _display displayCtrl IDC_rightTabContentListnBox; - _curSel = lnbCurSelRow _panel; - _selected = _panel lnbData [_curSel, 0]; +private _rightSort = ctrlIDC _sortControl == 17; +private _right = _rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}; - switch (_mode) do { - case 0: { - _panel lnbSort [1, false]; - }; - - case 1: { - _panel lnbSortByValue [0, false]; - }; - - case 2: { - for "_i" from 0 to (((lnbsize _panel) select 0) - 1) do { - _panel lnbSetText [[_i, 2], str (parseNumber (_panel lnbText [_i, 2]) / 1000)]; - }; - - _panel lnbSort [2, true]; - - - for "_i" from 0 to (((lnbsize _panel) select 0) - 1) do { - _panel lnbSetText [[_i, 2], str (parseNumber (_panel lnbText [_i, 2]) * 1000)]; - }; - }; - }; - - if (_cursel >= 0) then { - for '_i' from 0 to (((lnbsize _panel) select 0) - 1) do { - if ((_panel lnbdata [_i, 0]) == _selected) exitwith {_panel lnbSetCurSelRow _i}; - }; - }; -// Left panel +if (_rightSort) then { + [ + if (_right) then { + _display displayCtrl IDC_rightTabContentListnBox + } else { + _display displayCtrl IDC_rightTabContent + }, + switch (GVAR(currentRightPanel)) do { + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonThrow; + case IDC_buttonPut; + case IDC_buttonMag; + case IDC_buttonMagALL: { "CfgMagazines" }; + default { "CfgWeapons" }; + }, + GVAR(sortListRightPanel) select ( + switch (GVAR(currentRightPanel)) do { + case IDC_buttonOptic: { 0 }; + case IDC_buttonItemAcc: { 1 }; + case IDC_buttonMuzzle: { 2 }; + case IDC_buttonBipod: { 3 }; + case IDC_buttonCurrentMag; + case IDC_buttonCurrentMag2; + case IDC_buttonMag; + case IDC_buttonMagALL: { 4 }; + case IDC_buttonThrow: { 5 }; + case IDC_buttonPut: { 6 }; + case IDC_buttonMisc: { 7 }; + } + ) + ] } else { - _panel = _display displayCtrl ([IDC_leftTabContent, IDC_rightTabContent] select (ctrlIDC _control == 17)); - _curSel = lbCurSel _panel; - _selected = _panel lbData _curSel; + [ + _display displayCtrl IDC_leftTabContent, + switch (GVAR(currentLeftPanel)) do { + case IDC_buttonBackpack: { "CfgVehicles" }; + case IDC_buttonGoggles: { "CfgGlasses" }; + default { "CfgWeapons" }; + }, + (GVAR(sortListLeftPanel) select ([ + IDC_buttonPrimaryWeapon, + IDC_buttonHandgun, + IDC_buttonSecondaryWeapon, + IDC_buttonUniform, + IDC_buttonVest, + IDC_buttonBackpack, + IDC_buttonHeadgear, + IDC_buttonGoggles, + IDC_buttonNVG, + IDC_buttonBinoculars, + IDC_buttonMap, + IDC_buttonGPS, + IDC_buttonRadio, + IDC_buttonCompass, + IDC_buttonWatch + ] find GVAR(currentLeftPanel))) + ] +} params ["_panel", "_cfgClass", "_sorts"]; - if (_mode > 0) then { - lbSortByValue _panel; +private _curSel = if (_right) then { + lnbCurSelRow _panel +} else { + lbCurSel _panel +}; +private _selected = if (_right) then { + _panel lnbData [_curSel, 0]; +} else { + _panel lbData _curSel +}; + +private _mode = 0 max lbCurSel _sortControl; +private _statement = _sorts select _mode select 2; + +missionNamespace setVariable [ + [QGVAR(lastSortLeft), QGVAR(lastSortRight)] select _rightSort, + _sorts select _mode select 1 +]; + +private _for = if (_right) then { + for '_i' from 0 to ((lnbSize _panel select 0) - 1) +} else { + for '_i' from 1 to (lbSize _panel - 1) +}; + +_for do { + private _item = if (_right) then { + _panel lnbData [_i, 0] } else { - lbsort _panel; + _panel lbData _i }; - - if (_cursel >= 0) then { - for '_i' from 0 to (lbsize _panel - 1) do { - if ((_panel lbdata _i) == _selected) exitwith {_panel lbSetCurSel _i}; - }; + private _itemCfg = configFile >> _cfgClass >> _item; + private _value = _itemCfg call _statement; + if (_value isEqualType 0) then { + _value = [_value, 8] call CBA_fnc_formatNumber; + }; + if (_value isEqualTo "") then { + _value = "_"; + }; + if (_right) then { + _panel lnbSetText [[_i, 1], format ["%1%2", _value, _panel lnbText [_i, 1]]]; + } else { + _panel lbSetText [_i, format ["%1%2", _value, _panel lbText _i]]; + }; +}; + +if (_right) then { + _panel lnbSort [1, false]; + + _for do { + private _data = _panel lnbData [_i, 0]; + if (_cursel >= 0) then { + if (_data == _selected) then {_panel lnbSetCurSelRow _i}; + }; + _panel lnbSetText [[_i, 1], getText (configFile >> _cfgClass >> _data >> "displayName")]; + }; +} else { + lbSort [_panel, "ASC"]; + + _for do { + private _data = _panel lbData _i; + if (_cursel >= 0) then { + if (_data == _selected) then {_panel lbSetCurSel _i}; + }; + _panel lbSetText [_i, getText (configFile >> _cfgClass >> _data >> "displayName")]; }; }; diff --git a/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf b/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf new file mode 100644 index 0000000000..5207f3c1a4 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Alganthe, SynixeBrett + * Statement to sort weapons by their accuracy. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _fireModes = getArray (_config >> "modes"); +private _dispersion = []; + +{ + if (getNumber (_config >> _x >> "showToPlayer") != 0) then { + private _n = log getNumber (_config >> _x >> "dispersion"); + + if (!finite _n) then { + _n = 0; + }; + + _dispersion pushBackUnique _n; + }; +} foreach _fireModes; + +_dispersion sort true; + +10000000 - round ((_dispersion param [0, 0]) * 100000) diff --git a/addons/arsenal/functions/fnc_sortStatement_magCount.sqf b/addons/arsenal/functions/fnc_sortStatement_magCount.sqf new file mode 100644 index 0000000000..4c056d5147 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_magCount.sqf @@ -0,0 +1,17 @@ +#include "script_component.hpp" +/* + * Author: SynixeBrett + * Statement to sort magazines by their ammo count. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +getNumber (_config >> "count") diff --git a/addons/arsenal/functions/fnc_sortStatement_mass.sqf b/addons/arsenal/functions/fnc_sortStatement_mass.sqf new file mode 100644 index 0000000000..cfba8a6043 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_mass.sqf @@ -0,0 +1,27 @@ +#include "script_component.hpp" +/* + * Author: Alganthe, SynixeBrett + * Statement to sort items by their mass. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _mass = getNumber (_config >> "mass"); + +if (_mass == 0 && {isClass (_config >> "itemInfo")}) then { + _mass = getNumber (_config >> "itemInfo" >> "mass"); +}; + +if (_mass == 0 && {isClass (_config >> "WeaponSlotsInfo")}) then { + _mass = getNumber (_config >> "WeaponSlotsInfo" >> "mass"); +}; + +_mass diff --git a/addons/arsenal/functions/fnc_sortStatement_mod.sqf b/addons/arsenal/functions/fnc_sortStatement_mod.sqf new file mode 100644 index 0000000000..3fabb7f4ce --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_mod.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: SynixeBrett + * Statement to sort items by the mod they belong to. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Mod Name to Sort By + * + * Public: No +*/ + +params ["_config"]; + +private _dlc = ""; +private _addons = configSourceAddonList _config; +if !(_addons isEqualTo []) then { + private _mods = configSourceModList (configfile >> "CfgPatches" >> _addons select 0); + if !(_mods isEqualTo []) then { + _dlc = _mods select 0; + }; +}; + +modParams [_dlc, ["name"]] param [0, ""] diff --git a/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf b/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf new file mode 100644 index 0000000000..2c1d3a90f2 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf @@ -0,0 +1,26 @@ +#include "script_component.hpp" +/* + * Author: Alganthe, SynixeBrett + * Statement to sort weapons by their rate of fire. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _fireModes = getArray (_config >> "modes"); +private _fireRate = []; + +{ + _fireRate pushBackUnique getNumber (_config >> _x >> "reloadTime"); +} foreach _fireModes; + +_fireRate sort true; + +round (60 / (_fireRate param [0, 0])) diff --git a/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf new file mode 100644 index 0000000000..29891a2fe3 --- /dev/null +++ b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf @@ -0,0 +1,24 @@ +#include "script_component.hpp" +/* + * Author: Alganthe, SynixeBrett + * Statement to sort optics by their magnification. + * + * Arguments: + * 0: Item Config + * + * Return Value: + * Sorting Value + * + * Public: No +*/ + +params ["_config"]; + +private _minZoom = 999; // FOV, so smaller is more zoomed in +{ + _minZoom = _minZoom min getNumber (_x >> "opticsZoomMin"); +} forEach configProperties [_config >> "ItemInfo" >> "OpticsModes", "isClass _x"]; + +if (_minZoom in [0, 999]) exitWith {"?"}; + +round ((0.25 / _minZoom) * 10) diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index f92d10b879..6a0b4ec7d9 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -380,6 +380,26 @@ Seřadit podle množství Miktara göre sırala + + Sort by load + Nach Tragelast sortieren + + + Sort by accuracy + Nach Genauigkeit sortieren + + + Sort by rate of fire + Nach Schussrate sortieren + + + Sort by magnification + Nach Vergrößerung sortieren + + + Sort by ammo count + Nach Munitionszahl sortieren + Share or stop sharing the selected loadout Compartir o dejar de compartir el equipamiento seleccionado diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index 7f452a55eb..036e5d9f3d 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -523,32 +523,10 @@ class GVAR(display) { h = QUOTE(6 * GRID_H); onLBSelChanged = QUOTE(_this call FUNC(sortPanel)); sizeEx = QUOTE(5 * GRID_H); - class Items { - class Alphabet { - text="$STR_a3_rscdisplayarsenal_sort_alphabet"; - default=1; - value= 0; - }; - class Mod { - text="$STR_a3_rscdisplayarsenal_sort_mod"; - value= 1; - }; - }; }; class sortRightTab: sortLeftTab { idc = IDC_sortRightTab; x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); - class Items { - class Alphabet { - text="$STR_a3_rscdisplayarsenal_sort_alphabet"; - default=1; - value= 0; - }; - class Weight { - text="$STR_a3_rscdisplayarsenal_sort_mod"; - value= 1; - }; - }; }; class leftSearchbar: ctrlEdit { idc = IDC_leftSearchbar;