From df303337c75b83f4483f100b73a19df029e44c7a Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 18 Sep 2022 11:15:37 +0200 Subject: [PATCH 01/24] Arsenal update --- addons/arsenal/ACE_Arsenal_Sorts.hpp | 2 +- addons/arsenal/ACE_Arsenal_Stats.hpp | 5 +- addons/arsenal/XEH_PREP.hpp | 2 + addons/arsenal/XEH_postInit.sqf | 71 ++- addons/arsenal/XEH_preInit.sqf | 36 +- addons/arsenal/defines.hpp | 243 +++---- .../functions/fnc_addDefaultLoadout.sqf | 91 +-- .../arsenal/functions/fnc_addListBoxItem.sqf | 57 +- .../functions/fnc_addRightPanelButton.sqf | 52 +- addons/arsenal/functions/fnc_addSort.sqf | 23 +- addons/arsenal/functions/fnc_addStat.sqf | 53 +- .../arsenal/functions/fnc_addVirtualItems.sqf | 343 +++++----- .../functions/fnc_attributeAddCompatible.sqf | 35 +- .../functions/fnc_attributeAddItems.sqf | 92 +-- .../functions/fnc_attributeCategory.sqf | 2 +- .../arsenal/functions/fnc_attributeClear.sqf | 12 +- .../functions/fnc_attributeDblClick.sqf | 2 +- .../arsenal/functions/fnc_attributeImport.sqf | 42 +- .../arsenal/functions/fnc_attributeInit.sqf | 3 +- .../functions/fnc_attributeKeyDown.sqf | 11 +- .../arsenal/functions/fnc_attributeLoad.sqf | 8 +- .../arsenal/functions/fnc_attributeMode.sqf | 2 +- .../arsenal/functions/fnc_attributeSelect.sqf | 12 +- addons/arsenal/functions/fnc_buttonCargo.sqf | 131 ++-- .../arsenal/functions/fnc_buttonClearAll.sqf | 61 +- addons/arsenal/functions/fnc_buttonExport.sqf | 22 +- addons/arsenal/functions/fnc_buttonHide.sqf | 9 +- addons/arsenal/functions/fnc_buttonImport.sqf | 112 ++-- .../functions/fnc_buttonLoadoutsDelete.sqf | 30 +- .../functions/fnc_buttonLoadoutsLoad.sqf | 96 +-- .../functions/fnc_buttonLoadoutsRename.sqf | 60 +- .../functions/fnc_buttonLoadoutsSave.sqf | 313 +++------- .../functions/fnc_buttonLoadoutsShare.sqf | 24 +- addons/arsenal/functions/fnc_buttonStats.sqf | 4 +- .../arsenal/functions/fnc_buttonStatsPage.sqf | 2 +- .../arsenal/functions/fnc_clearSearchbar.sqf | 2 +- addons/arsenal/functions/fnc_compileSorts.sqf | 3 +- addons/arsenal/functions/fnc_compileStats.sqf | 23 +- .../arsenal/functions/fnc_fillLeftPanel.sqf | 226 ++++--- .../functions/fnc_fillLoadoutsList.sqf | 88 +-- .../arsenal/functions/fnc_fillRightPanel.sqf | 390 ++++++------ addons/arsenal/functions/fnc_fillSort.sqf | 56 +- addons/arsenal/functions/fnc_getLoadout.sqf | 10 +- .../functions/fnc_handleLoadoutsSearchbar.sqf | 60 +- addons/arsenal/functions/fnc_handleMouse.sqf | 53 +- .../functions/fnc_handleScrollWheel.sqf | 8 +- .../arsenal/functions/fnc_handleSearchbar.sqf | 167 +++-- addons/arsenal/functions/fnc_handleStats.sqf | 8 +- addons/arsenal/functions/fnc_initBox.sqf | 62 +- addons/arsenal/functions/fnc_itemInfo.sqf | 56 +- .../functions/fnc_loadoutsChangeTab.sqf | 32 +- addons/arsenal/functions/fnc_message.sqf | 30 +- .../arsenal/functions/fnc_onArsenalClose.sqf | 43 +- .../arsenal/functions/fnc_onArsenalOpen.sqf | 296 ++++----- addons/arsenal/functions/fnc_onKeyDown.sqf | 109 ++-- .../arsenal/functions/fnc_onLoadoutsClose.sqf | 8 +- .../arsenal/functions/fnc_onLoadoutsOpen.sqf | 4 +- .../functions/fnc_onSelChangedLeft.sqf | 591 ++++++++++++------ .../functions/fnc_onSelChangedLoadouts.sqf | 43 +- .../functions/fnc_onSelChangedRight.sqf | 108 ++-- .../fnc_onSelChangedRightListnBox.sqf | 58 +- addons/arsenal/functions/fnc_open3DEN.sqf | 3 +- addons/arsenal/functions/fnc_openBox.sqf | 29 +- .../arsenal/functions/fnc_portVALoadouts.sqf | 39 +- addons/arsenal/functions/fnc_removeBox.sqf | 29 +- addons/arsenal/functions/fnc_removeStat.sqf | 15 +- .../functions/fnc_removeVirtualItems.sqf | 94 +-- .../fnc_replaceUniqueItemsLoadout.sqf | 112 ++++ addons/arsenal/functions/fnc_scanConfig.sqf | 270 ++++---- addons/arsenal/functions/fnc_showItem.sqf | 62 +- addons/arsenal/functions/fnc_sortPanel.sqf | 72 ++- .../functions/fnc_sortStatement_accuracy.sqf | 3 +- .../functions/fnc_sortStatement_mod.sqf | 13 +- .../fnc_sortStatement_protection.sqf | 8 +- .../fnc_sortStatement_rateOfFire.sqf | 4 +- .../functions/fnc_sortStatement_scopeMag.sqf | 1 + .../fnc_statBarStatement_accuracy.sqf | 16 +- .../fnc_statBarStatement_default.sqf | 12 +- .../functions/fnc_statBarStatement_impact.sqf | 19 +- .../fnc_statBarStatement_rateOfFIre.sqf | 19 +- .../fnc_statTextStatement_accuracy.sqf | 20 +- .../fnc_statTextStatement_explosionTime.sqf | 10 +- .../functions/fnc_statTextStatement_mass.sqf | 9 +- .../fnc_statTextStatement_rateOfFire.sqf | 17 +- .../fnc_statTextStatement_scopeMag.sqf | 9 +- .../fnc_statTextStatement_scopeVisionMode.sqf | 35 +- .../fnc_statTextStatement_smokeChemTTL.sqf | 13 +- addons/arsenal/functions/fnc_updateCamPos.sqf | 10 +- .../functions/fnc_updateCurrentItemsList.sqf | 81 +++ .../functions/fnc_updateRightPanel.sqf | 55 +- .../functions/fnc_updateUniqueItemsList.sqf | 158 +++-- .../arsenal/functions/fnc_verifyLoadout.sqf | 369 ++++++----- .../missions/Arsenal.VR/XEH_postInit.sqf | 31 +- .../missions/Arsenal.VR/fnc_createTarget.sqf | 15 +- .../missions/Arsenal.VR/fnc_onPause.sqf | 17 +- .../missions/Arsenal.VR/initPlayerLocal.sqf | 84 ++- addons/common/XEH_PREP.hpp | 4 + addons/common/XEH_postInit.sqf | 7 +- addons/common/XEH_preStart.sqf | 10 + addons/common/functions/fnc_addWeapon.sqf | 59 ++ addons/common/functions/fnc_baseWeapon.sqf | 62 ++ addons/common/functions/fnc_getAddon.sqf | 39 ++ addons/common/functions/fnc_getConfigName.sqf | 42 ++ docs/wiki/framework/arsenal-framework.md | 104 ++- 104 files changed, 3774 insertions(+), 2903 deletions(-) create mode 100644 addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf create mode 100644 addons/arsenal/functions/fnc_updateCurrentItemsList.sqf create mode 100644 addons/common/functions/fnc_addWeapon.sqf create mode 100644 addons/common/functions/fnc_baseWeapon.sqf create mode 100644 addons/common/functions/fnc_getAddon.sqf create mode 100644 addons/common/functions/fnc_getConfigName.sqf diff --git a/addons/arsenal/ACE_Arsenal_Sorts.hpp b/addons/arsenal/ACE_Arsenal_Sorts.hpp index 22e618c1e48..a3b5f80d28a 100644 --- a/addons/arsenal/ACE_Arsenal_Sorts.hpp +++ b/addons/arsenal/ACE_Arsenal_Sorts.hpp @@ -4,7 +4,7 @@ class GVAR(sorts) { displayName = ""; tabs[] = {{}, {}}; statement = ""; - condition = "true"; + condition = QUOTE(true); }; class ACE_alphabetically: sortBase { diff --git a/addons/arsenal/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp index a69b0545fb0..3528a7694b8 100644 --- a/addons/arsenal/ACE_Arsenal_Stats.hpp +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -8,7 +8,7 @@ class GVAR(stats) { showText = 0; barStatement = ""; textStatement = ""; - condition = "true"; + condition = QUOTE(true); tabs[] = {{}, {}}; }; class ACE_bananaPotassium: statBase { @@ -63,7 +63,7 @@ class GVAR(stats) { 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)); + barStatement = QUOTE([ARR_3(_this select 0, _this select 1, [ARR_2([ARR_2(0, 3.2)], [ARR_2(-1, 1100)])])] call FUNC(statBarStatement_impact)); tabs[] = {{0,1,2}, {}}; }; class ACE_scopeMagnification: statBase { @@ -125,7 +125,6 @@ class GVAR(stats) { displayName = CSTRING(StatExplosionTime); showText = 1; textStatement = QUOTE(call FUNC(statTextStatement_explosionTime)); - condition = QUOTE(true); tabs[] = {{}, {5}}; }; }; diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 93349007890..d4c96d7ba03 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -61,6 +61,7 @@ PREP(portVALoadouts); PREP(removeBox); PREP(removeStat); PREP(removeVirtualItems); +PREP(replaceUniqueItemsLoadout); PREP(scanConfig); PREP(showItem); PREP(sortPanel); @@ -85,5 +86,6 @@ PREP(statTextStatement_scopeVisionMode); PREP(statTextStatement_smokeChemTTL); PREP(updateCamPos); PREP(updateRightPanel); +PREP(updateCurrentItemsList); PREP(updateUniqueItemsList); PREP(verifyLoadout); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index ea1b59c6aef..6b04af6d922 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -10,8 +10,8 @@ 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; +[QGVAR(initBox), {LINKFUNC(initBox)}] call CBA_fnc_addEventHandler; +[QGVAR(removeBox), {LINKFUNC(removeBox)}] call CBA_fnc_addEventHandler; [QGVAR(broadcastFace), { params ["_unit", "_face"]; @@ -28,24 +28,21 @@ GVAR(lastSortRight) = ""; [QGVAR(loadoutUnshared), { params ["_contentPanelCtrl" , "_playerName", "_loadoutName"]; + // If player is in arsenal in the shared tab and a loadout is unshared at the same time if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { - private _dataToCheck = _playerName + _loadoutName; - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbData [_i, 1]) == _dataToCheck) exitwith {_contentPanelCtrl lnbDeleteRow _i}; + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbData [_lbIndex, 1]) == _dataToCheck) exitWith { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; }; } else { - - if ( - profileName == _playerName && - {!(isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts})} - ) then { - - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _loadoutName) exitwith { - _contentPanelCtrl lnbSetPicture [[_i, 0], QPATHTOF(data\iconPublicBlank.paa)]; - _contentPanelCtrl lnbSetValue [[_i, 0], 0]; + if (profileName == _playerName && {!(isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts})}) then { + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _loadoutName) exitWith { + _contentPanelCtrl lnbSetPicture [[_lbIndex, 0], QPATHTOF(data\iconPublicBlank.paa)]; + _contentPanelCtrl lnbSetValue [[_lbIndex, 0], 0]; }; }; }; @@ -53,26 +50,27 @@ GVAR(lastSortRight) = ""; }] call CBA_fnc_addEventHandler; [QGVAR(loadoutShared), { - params ["_contentPanelCtrl" ,"_loadoutArgs"]; + params ["_contentPanelCtrl", "_loadoutArgs"]; _loadoutArgs params ["_playerName", "_loadoutName", "_loadoutData"]; + // If player is in arsenal in the shared tab and a loadout is shared at the same time if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { + private _curSelData = _contentPanelCtrl lnbData [lnbCurSelRow _contentPanelCtrl, 1]; - private _curSelData =_contentPanelCtrl lnbData [(lnbCurSelRow _contentPanelCtrl), 1]; ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + _extendedLoadout params ["_loadout"]; private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; + private _cfgWeapons = configFile >> "CfgWeapons"; - _extendedLoadout params ["_loadout"]; ADD_LOADOUTS_LIST_PICTURES _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; + // Set color of row, depending if items are unavailable/missing if (_nullItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; } else { - if (_unavailableItemsAmount > 0) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; }; @@ -81,25 +79,46 @@ GVAR(lastSortRight) = ""; _contentPanelCtrl lnbSort [1, false]; // Select previously selected loadout - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _curSelData) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _curSelData) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex + }; }; }; }] call CBA_fnc_addEventHandler; ["CBA_loadoutSet", { params ["_unit", "_loadout", "_extendedInfo"]; + + // Set face private _face = _extendedInfo getOrDefault [QGVAR(face), ""]; + if (_face != "") then { - _unit setFace _face; + if (isMultiplayer) then { + private _id = [QGVAR(broadcastFace), [_unit, _face], QGVAR(centerFace_) + netId _unit] call CBA_fnc_globalEventJIP; + [_id, _unit] call CBA_fnc_removeGlobalEventJIP; + } else { + _unit setFace _face; + }; }; + + // Set voice private _voice = _extendedInfo getOrDefault [QGVAR(voice), ""]; + if (_voice != "") then { - _unit setSpeaker _voice; + if (isMultiplayer) then { + private _id = [QGVAR(broadcastVoice), [_unit, _voice], QGVAR(centerVoice_) + netId _unit] call CBA_fnc_globalEventJIP; + [_id, _unit] call CBA_fnc_removeGlobalEventJIP; + } else { + _unit setSpeaker _voice; + }; }; + + // Set insignia private _insignia = _extendedInfo getOrDefault [QGVAR(insignia), ""]; + if (_insignia != "") then { - _unit setVariable ["BIS_fnc_setUnitInsignia_class", nil]; - [_unit, _insignia] call bis_fnc_setUnitInsignia; + [_unit, ""] call BIS_fnc_setUnitInsignia; + [_unit, _insignia] call BIS_fnc_setUnitInsignia; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 36c8adb46fc..35710cbb132 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -8,20 +8,21 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; // Arsenal -[QGVAR(camInverted), "CHECKBOX", localize LSTRING(invertCameraSetting), localize LSTRING(settingCategory), false] call CBA_fnc_addSetting; -[QGVAR(enableModIcons), "CHECKBOX", [LSTRING(modIconsSetting), LSTRING(modIconsTooltip)], localize LSTRING(settingCategory), true] call CBA_fnc_addSetting; -[QGVAR(fontHeight), "SLIDER", [LSTRING(fontHeightSetting), LSTRING(fontHeightTooltip)], localize LSTRING(settingCategory), [1, 10, 4.5, 1]] call CBA_fnc_addSetting; -[QGVAR(enableIdentityTabs), "CHECKBOX", localize LSTRING(enableIdentityTabsSettings), localize LSTRING(settingCategory), true, true] call CBA_fnc_addSetting; +[QGVAR(camInverted), "CHECKBOX", LLSTRING(invertCameraSetting), LLSTRING(settingCategory), false] call CBA_fnc_addSetting; +[QGVAR(enableModIcons), "CHECKBOX", [LSTRING(modIconsSetting), LSTRING(modIconsTooltip)], LLSTRING(settingCategory), true] call CBA_fnc_addSetting; +[QGVAR(fontHeight), "SLIDER", [LSTRING(fontHeightSetting), LSTRING(fontHeightTooltip)], LLSTRING(settingCategory), [1, 10, 4.5, 1]] call CBA_fnc_addSetting; +[QGVAR(enableIdentityTabs), "CHECKBOX", LLSTRING(enableIdentityTabsSettings), LLSTRING(settingCategory), true, true] call CBA_fnc_addSetting; // Arsenal loadouts -[QGVAR(allowDefaultLoadouts), "CHECKBOX", [LSTRING(allowDefaultLoadoutsSetting), LSTRING(defaultLoadoutsTooltip)], [localize LSTRING(settingCategory), localize LSTRING(loadoutSubcategory)], true, true] call CBA_fnc_addSetting; -[QGVAR(allowSharedLoadouts), "CHECKBOX", localize LSTRING(allowSharingSetting), [localize LSTRING(settingCategory), localize LSTRING(loadoutSubcategory)], true, true] call CBA_fnc_addSetting; -[QGVAR(EnableRPTLog), "CHECKBOX", [LSTRING(printToRPTSetting), LSTRING(printToRPTTooltip)], [localize LSTRING(settingCategory), localize LSTRING(loadoutSubcategory)], false, false] call CBA_fnc_addSetting; +[QGVAR(allowDefaultLoadouts), "CHECKBOX", [LSTRING(allowDefaultLoadoutsSetting), LSTRING(defaultLoadoutsTooltip)], [LLSTRING(settingCategory), LLSTRING(loadoutSubcategory)], true, true] call CBA_fnc_addSetting; +[QGVAR(allowSharedLoadouts), "CHECKBOX", LLSTRING(allowSharingSetting), [LLSTRING(settingCategory), LLSTRING(loadoutSubcategory)], true, true] call CBA_fnc_addSetting; +[QGVAR(EnableRPTLog), "CHECKBOX", [LSTRING(printToRPTSetting), LSTRING(printToRPTTooltip)], [LLSTRING(settingCategory), LLSTRING(loadoutSubcategory)], false, false] call CBA_fnc_addSetting; -[QGVAR(loadoutsSaveFace), "CHECKBOX", localize LSTRING(loadoutsSaveFaceSetting), [localize LSTRING(settingCategory), localize LSTRING(loadoutSubcategory)], false] call CBA_fnc_addSetting; -[QGVAR(loadoutsSaveVoice), "CHECKBOX", localize LSTRING(loadoutsSaveVoiceSetting), [localize LSTRING(settingCategory), localize LSTRING(loadoutSubcategory)], false] call CBA_fnc_addSetting; -[QGVAR(loadoutsSaveInsignia), "CHECKBOX", localize LSTRING(loadoutsSaveInsigniaSetting), [localize LSTRING(settingCategory), localize LSTRING(loadoutSubcategory)], true] call CBA_fnc_addSetting; +[QGVAR(loadoutsSaveFace), "CHECKBOX", LLSTRING(loadoutsSaveFaceSetting), [LLSTRING(settingCategory), LLSTRING(loadoutSubcategory)], false] call CBA_fnc_addSetting; +[QGVAR(loadoutsSaveVoice), "CHECKBOX", LLSTRING(loadoutsSaveVoiceSetting), [LLSTRING(settingCategory), LLSTRING(loadoutSubcategory)], false] call CBA_fnc_addSetting; +[QGVAR(loadoutsSaveInsignia), "CHECKBOX", LLSTRING(loadoutsSaveInsigniaSetting), [LLSTRING(settingCategory), LLSTRING(loadoutSubcategory)], true] call CBA_fnc_addSetting; +// Arsenal events [QGVAR(statsToggle), { params ["_display", "_showStats"]; @@ -54,7 +55,6 @@ PREP_RECOMPILE_END; _this call FUNC(buttonStatsPage); }] call CBA_fnc_addEventHandler; - [QGVAR(displayStats), { _this call FUNC(handleStats); }] call CBA_fnc_addEventHandler; @@ -62,17 +62,21 @@ PREP_RECOMPILE_END; call FUNC(compileStats); call FUNC(compileSorts); +// Caches for names, pictures, mod icons +GVAR(addListBoxItemCache) = createHashMap; +GVAR(rightPanelCache) = createHashMap; + [QUOTE(ADDON), {!isNil QGVAR(camera)}] call CBA_fnc_registerFeatureCamera; -// Compatibility with CBA scripted optics and dispoable framework +// Compatibility with CBA scripted optics and disposable framework [QGVAR(displayOpened), { - "cba_optics_arsenalOpened" call CBA_fnc_localEvent; - "cba_disposable_arsenalOpened" call CBA_fnc_localEvent; + "CBA_optics_arsenalOpened" call CBA_fnc_localEvent; + "CBA_disposable_arsenalOpened" call CBA_fnc_localEvent; }] call CBA_fnc_addEventHandler; [QGVAR(displayClosed), { - "cba_optics_arsenalClosed" call CBA_fnc_localEvent; - "cba_disposable_arsenalClosed" call CBA_fnc_localEvent; + "CBA_optics_arsenalClosed" call CBA_fnc_localEvent; + "CBA_disposable_arsenalClosed" call CBA_fnc_localEvent; }] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 70292c3e7c3..8d8a37ada8f 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -7,6 +7,14 @@ #define WIDTH_GAP (WIDTH_TOTAL / 100) #define WIDTH_SINGLE ((WIDTH_TOTAL - 6 * WIDTH_GAP) / 5) +// IDDs +#define IDD_MISSION 46 +#define IDD_RSCDISPLAYCURATOR 312 +#define IDD_DISPLAY3DEN 313 + +#define IDC_OK 1 // emulate "OK" button +#define IDC_CANCEL 2 // emulate "Cancel" button + // IDCs #define IDD_ace_arsenal 1127001 #define IDC_mouseArea 0 @@ -165,9 +173,57 @@ #define IDC_ATTRIBUTE_IMPORT_BUTTON 8109 #define IDC_ATTRIBUTE_ADD_COMPATIBLE 8110 +// Weapons 0 [primary, handgun, secondary] +// Weapon attachements 1 [optics, flashlight, muzzle, bipod] +// Magazines 2 +// Headgear 3 +// Uniform 4 +// Vest 5 +// Backpacks 6 +// Goggles 7 +// NVGs 8 +// Binoculars 9 +// Map 10 +// Compass 11 +// Radio slot 12 +// Watch slot 13 +// Comms slot (GPS, UAV terminals) 14 +// Grenades (WeaponThrow) 15 +// Explosives (WeaponPut) 16 +// InventoryItems 17 +#define EMPTY_VIRTUAL_ARSENAL\ +[\ + [[],[],[]],\ + [[],[],[],[]],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + [],\ + []\ +] + // Indexes of virtual items array #define IDX_VIRT_WEAPONS 0 -#define IDX_VIRT_ATTACHEMENTS 1 +#define IDX_VIRT_PRIMARY_WEAPONS 0 +#define IDX_VIRT_SECONDARY_WEAPONS 1 +#define IDX_VIRT_HANDGUN_WEAPONS 2 + +#define IDX_VIRT_ATTACHMENTS 1 +#define IDX_VIRT_OPTICS_ATTACHMENTS 0 +#define IDX_VIRT_FLASHLIGHT_ATTACHMENTS 1 +#define IDX_VIRT_MUZZLE_ATTACHMENTS 2 +#define IDX_VIRT_BIPOD_ATTACHMENTS 3 #define IDX_VIRT_ITEMS_ALL 2 @@ -183,6 +239,53 @@ #define IDX_VIRT_RADIO 12 #define IDX_VIRT_WATCH 13 #define IDX_VIRT_COMMS 14 +#define IDX_VIRT_GRENADES 15 +#define IDX_VIRT_EXPLOSIVES 16 +#define IDX_VIRT_MISC_ITEMS 17 + +#define IDX_VIRT_UNIQUE_MISC_ITEMS 18 +#define IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL 19 +#define IDX_VIRT_UNIQUE_GRENADES 20 +#define IDX_VIRT_UNIQUE_EXPLOSIVES 21 +#define IDX_VIRT_UNIQUE_ATTACHMENTS 22 +#define IDX_VIRT_UNIQUE_BACKPACKS 23 +#define IDX_VIRT_UNIQUE_GOGGLES 24 + +// Indexes of current items array +#define IDX_CURR_PRIMARY_WEAPON 0 +#define IDX_CURR_SECONDARY_WEAPON 1 +#define IDX_CURR_HANDGUN_WEAPON 2 +#define IDX_CURR_HEADGEAR 3 +#define IDX_CURR_UNIFORM 4 +#define IDX_CURR_VEST 5 +#define IDX_CURR_BACKPACK 6 +#define IDX_CURR_GOGGLES 7 +#define IDX_CURR_NVG 8 +#define IDX_CURR_BINO 9 +#define IDX_CURR_MAP 10 +#define IDX_CURR_COMPASS 11 +#define IDX_CURR_RADIO 12 +#define IDX_CURR_WATCH 13 +#define IDX_CURR_COMMS 14 +#define IDX_CURR_UNIFORM_ITEMS 15 +#define IDX_CURR_VEST_ITEMS 16 +#define IDX_CURR_BACKPACK_ITEMS 17 +#define IDX_CURR_PRIMARY_WEAPON_ITEMS 18 +#define IDX_CURR_SECONDARY_WEAPON_ITEMS 19 +#define IDX_CURR_HANDGUN_WEAPON_ITEMS 20 +#define IDX_CURR_BINO_ITEMS 21 + +// Indexes of loadout items array +#define IDX_LOADOUT_PRIMARY_WEAPON 0 +#define IDX_LOADOUT_SECONDARY_WEAPON 1 +#define IDX_LOADOUT_HANDGUN_WEAPON 2 +#define IDX_LOADOUT_UNIFORM 3 +#define IDX_LOADOUT_VEST 4 +#define IDX_LOADOUT_BACKPACK 5 +#define IDX_LOADOUT_HEADGEAR 6 +#define IDX_LOADOUT_GOGGLES 7 +#define IDX_LOADOUT_BINO 8 +#define IDX_LOADOUT_ASSIGNEDITEMS 9 #define SYMBOL_ITEM_NONE "−" #define SYMBOL_ITEM_REMOVE "×" @@ -199,31 +302,6 @@ #define RIGHT_PANEL_ITEMS_BACKGROUND_IDCS IDC_iconBackgroundMag, IDC_iconBackgroundMagALL, IDC_iconBackgroundThrow, IDC_iconBackgroundPut, IDC_iconBackgroundMisc, RIGHT_PANEL_CUSTOM_BACKGROUND #define ARROWS_IDCS IDC_arrowMinus, IDC_arrowPlus -#define GETDLC\ - {\ - private _dlc = "";\ - private _addons = configsourceaddonlist _this;\ - if (count _addons > 0) then {\ - private _mods = configsourcemodlist (configfile >> "CfgPatches" >> _addons select 0);\ - if (count _mods > 0) then {\ - _dlc = _mods select 0;\ - };\ - };\ - _dlc\ - } - -#define ADDMODICON\ - {\ - private _dlcName = _this call GETDLC;\ - if (_dlcName != "") then {\ - _ctrlPanel lbsetpictureright [_lbAdd,(modParams [_dlcName,["logo"]]) param [0,""]];\ - };\ - }; - -#define ADDBINOCULARSMAG\ - private _magazines = getarray (configfile >> "cfgweapons" >> _item >> "magazines");\ - if (count _magazines > 0) then {GVAR(center) addmagazine (_magazines select 0)}; - #define TOGGLE_RIGHT_PANEL_WEAPON\ {\ _x = _display displayCtrl _x;\ @@ -231,7 +309,7 @@ _x ctrlShow true;\ _x ctrlEnable true;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground,\ IDC_rightTabContent,\ @@ -242,15 +320,9 @@ IDC_buttonCurrentMag\ ];\ private _buttonCurrentMag2Ctrl = _display displayCtrl IDC_buttonCurrentMag2;\ -if (GVAR(currentLeftPanel) == IDC_buttonPrimaryWeapon) then {\ - _buttonCurrentMag2Ctrl ctrlSetFade 0;\ - _buttonCurrentMag2Ctrl ctrlShow true;\ - _buttonCurrentMag2Ctrl ctrlEnable true;\ -} else {\ - _buttonCurrentMag2Ctrl ctrlSetFade 1;\ - _buttonCurrentMag2Ctrl ctrlShow false;\ - _buttonCurrentMag2Ctrl ctrlEnable false;\ -};\ +_buttonCurrentMag2Ctrl ctrlSetFade 0;\ +_buttonCurrentMag2Ctrl ctrlShow true;\ +_buttonCurrentMag2Ctrl ctrlEnable true;\ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ {\ _x = _display displayCtrl _x;\ @@ -258,7 +330,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow false;\ _x ctrlEnable false;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_loadIndicator,\ RIGHT_PANEL_ITEMS_IDCS,\ IDC_rightTabContentListnBox,\ @@ -274,7 +346,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ safezoneH - 28 * GRID_H\ ];\ _x ctrlCommit 0;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground\ ]; @@ -286,7 +358,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow true;\ _x ctrlEnable true;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame, \ IDC_blockRighttBackground,\ IDC_loadIndicator,\ @@ -304,7 +376,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ _x ctrlShow false;\ _x ctrlEnable false;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_buttonCurrentMag,\ IDC_buttonCurrentMag2,\ IDC_iconBackgroundCurrentMag,\ @@ -319,7 +391,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ safezoneH - 34 * GRID_H\ ];\ _x ctrlCommit 0;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground\ ];\ @@ -367,7 +439,7 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\ _x ctrlShow false;\ _x ctrlEnable false;\ _x ctrlCommit FADE_DELAY;\ -} foreach [\ +} forEach [\ IDC_blockRightFrame,\ IDC_blockRighttBackground,\ IDC_loadIndicator,\ @@ -387,83 +459,12 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\ IDC_iconBackgroundCurrentMag2\ ]; -#define LIST_DEFAULTS\ - [\ - [\ - (primaryweapon GVAR(center) call bis_fnc_baseWeapon),\ - (secondaryweapon GVAR(center) call bis_fnc_baseWeapon),\ - (handgunweapon GVAR(center) call bis_fnc_baseWeapon)\ - ],\ - [\ - [primaryWeaponItems GVAR(center), secondaryWeaponItems GVAR(center), handgunItems GVAR(center)],\ - [primaryWeaponMagazine GVAR(center), secondaryWeaponMagazine GVAR(center), handgunMagazine GVAR(center)]\ - ],\ - uniformItems GVAR(center) + vestItems GVAR(center) + backpackItems GVAR(center),\ - [headgear GVAR(center)],\ - [uniform GVAR(center)],\ - [vest GVAR(center)],\ - [backpack GVAR(center)],\ - [goggles GVAR(center)],\ - [hmd GVAR(center)],\ - [binocular GVAR(center)]\ -] - -#define CHECK_WEAPON_OR_ACC\ - (_weaponsArray select 0) findIf {_x == _item} > -1 ||\ - {(_weaponsArray select 1) findIf {_x == _item} > -1} ||\ - {(_weaponsArray select 2) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 9) findIf {_x == _item} > -1} ||\ - {(_accsArray select 0) findIf {_x == _item} > -1} ||\ - {(_accsArray select 1 findIf {_x == _item} > -1)} ||\ - {(_accsArray select 2) findIf {_x == _item} > -1} ||\ - {(_accsArray select 3) findIf {_x == _item} > -1} - -// PboProject 2.45 has problems with these macros for some reason, adding a single space before the \ fixes -#define CHECK_ASSIGNED_ITEMS \ - (GVAR(virtualItems) select 10) findIf {_x == _item} > -1 ||\ - {(GVAR(virtualItems) select 11) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 12) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 13) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 14) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 8) findIf {_x == _item} > -1} - -#define CHECK_CONTAINER \ - (GVAR(virtualItems) select 4) findIf {_x == _item} > -1 ||\ - {(GVAR(virtualItems) select 5) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 6) findIf {_x == _item} > -1} - -#define CLASS_CHECK_ITEM\ - isClass (_weaponCfg >> _item) ||\ - {isClass (_vehcCfg >> _item)} ||\ - {isClass (_glassesCfg >> _item)} ||\ - {isClass (_magCfg >> _item)} - -#define CHECK_CONTAINER_ITEMS \ - (GVAR(virtualItems) select 3) findIf {_x == _item} > -1 ||\ - {(_accsArray select 0) findIf {_x == _item} > -1} ||\ - {(_accsArray select 1) findIf {_x == _item} > -1} ||\ - {(_accsArray select 2) findIf {_x == _item} > -1} ||\ - {(_accsArray select 3) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 4) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 5) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 6) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 7) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 8) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 10) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 11) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 12) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 13) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 14) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 15) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 16) findIf {_x == _item} > -1} ||\ - {(GVAR(virtualItems) select 17) findIf {_x == _item} > -1} - #define ADD_LOADOUTS_LIST_PICTURES\ - _contentPanelCtrl lnbSetPicture [[_newRow, 2], getText (configFile >> "cfgWeapons" >> ((_loadout select 0) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 3], getText (configFile >> "cfgWeapons" >> ((_loadout select 1) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 4], getText (configFile >> "cfgWeapons" >> ((_loadout select 2) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 5], getText (configFile >> "cfgWeapons" >> ((_loadout select 3) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 6], getText (configFile >> "cfgWeapons" >> ((_loadout select 4) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "cfgVehicles" >> ((_loadout select 5) select 0) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (configFile >> "cfgWeapons" >> (_loadout select 6) >> "picture")];\ - _contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "cfgGlasses" >> (_loadout select 7) >> "picture")]; + _contentPanelCtrl lnbSetPicture [[_newRow, 2], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_PRIMARY_WEAPON) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 3], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_SECONDARY_WEAPON) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 4], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_HANDGUN_WEAPON) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 5], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_UNIFORM) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 6], getText (_cfgWeapons >> (_loadout select IDX_LOADOUT_VEST) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "CfgVehicles" >> (_loadout select IDX_LOADOUT_BACKPACK) select 0 >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (_cfgWeapons >> _loadout select IDX_LOADOUT_HEADGEAR >> "picture")];\ + _contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "CfgGlasses" >> _loadout select IDX_LOADOUT_GOGGLES >> "picture")]; diff --git a/addons/arsenal/functions/fnc_addDefaultLoadout.sqf b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf index 648a131a430..b5a8f82d1c0 100644 --- a/addons/arsenal/functions/fnc_addDefaultLoadout.sqf +++ b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" /* - * Author: 654wak654 + * Author: 654wak654, johnb43 * Adds a loadout to the "Default Loadouts" list. - * If a loadout with the same name exists, it is overwritten. + * If a loadout with a similar name exists (case insensitve), it is overwritten. * * Arguments: * 0: Name of loadout @@ -20,6 +20,8 @@ params [["_name", "", [""]], ["_loadout", [], [[]]]]; private _extendedInfo = createHashMap; + +// Check if CBA extended loadout array if (count _loadout == 2) then { _extendedInfo = _loadout select 1; _loadout = _loadout select 0; @@ -31,84 +33,15 @@ if (isNil QGVAR(defaultLoadoutsList)) then { GVAR(defaultLoadoutsList) = []; }; -for "_dataIndex" from 0 to 10 do { - switch (_dataIndex) do { - - case 0; - case 1; - case 2; - case 8: { - if (count (_loadout select _dataIndex) > 0) then { - - private _weapon = (_loadout select _dataIndex) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_loadout select _dataIndex) set [0, _baseWeapon]; - }; - }; - }; - }; - - case 3; - case 4; - case 5: { - if (count (_loadout select _dataIndex) > 0) then { - private _containerContents = (_loadout select _dataIndex) select 1; - - if (count _containerContents > 0) then { - - { - if (count _x == 2) then { - - if ((_x select 0) isEqualType "") then { - - private _item = (_x select 0); - if (_item != "") then { +// Replace unique items with their bases and replace weapons with their base weapons +_loadout = [_loadout] call FUNC(replaceUniqueItemsLoadout); - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { +private _index = GVAR(defaultLoadoutsList) findIf {(_x select 0) == _name}; - _x set [0, _uniqueBaseCfgText]; - }; - }; - } else { - private _weapon = (_x select 0) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_x select 0) set [0, _baseWeapon]; - }; - }; - }; - }; - } foreach _containerContents; - }; - }; - }; - - case 9: { - for "_subIndex" from 0 to 4 do { - private _item = (_loadout select _dataIndex) select _subIndex; - - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; - }; - }; - }; - }; - }; -}; - -private _loadoutIndex = (+(GVAR(defaultLoadoutsList))) findIf {(_x select 0) == _name}; -if (_loadoutIndex == -1) then { - GVAR(defaultLoadoutsList) pushBack [_name, [_loadout, _extendedInfo]]; +// If there is an already existing loadout with similar name, overwrite it +if (_index != -1) then { + GVAR(defaultLoadoutsList) set [_index, [_name, [_loadout, _extendedInfo]]]; } else { - GVAR(defaultLoadoutsList) set [_loadoutIndex, [_name, [_loadout, _extendedInfo]]]; + // Otherwise just add + GVAR(defaultLoadoutsList) pushBack [_name, [_loadout, _extendedInfo]]; }; diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index 53bf321bafc..928e2f7f61d 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -1,58 +1,57 @@ #include "script_component.hpp" /* - * Author: Dedmen + * Author: Dedmen, johnb43 * Add a listbox row. * * Arguments: - * 0: Config category (must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice") + * 0: Config category (must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice", "CfgGlasses" etc.) * 1: Classname * 2: Panel control - * 3: Name of the picture entry in that Cfg class + * 3: Name of the picture entry in that Cfg class (Optional) * * Return Value: * None * + * Example: + * ["CfgWeapons", "arifle_AKM_F", _control] call ace_arsenal_fnc_addListBoxItem + * * Public: Yes */ + params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]]; -private _cacheNamespace = _ctrlPanel; //For better readability. +// Sanitise, as it's public +private _itemInfo = toLower (_configCategory + _className); +private _cachedItemInfo = GVAR(addListBoxItemCache) getOrDefault [_itemInfo, []]; -private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; +// If not in cache, find info and cache it for later use +if (_cachedItemInfo isEqualTo []) then { + // Get classname (config case), display name, picture and DLC + private _configPath = configFile >> _configCategory >> _className; -//_cachedItemInfo == [_displayName, _itemPicture, _modPicture] -if (_cachedItemInfo isEqualTo []) then {//Not in cache. So get info and put into cache. + _cachedItemInfo set [0, configName _configPath]; + _cachedItemInfo set [1, getText (_configPath >> "displayName")]; - private _configPath = configFile >> _configCategory >> _className; + // If _pictureEntryName is empty, then this item has no picture (e.g. faces) + _cachedItemInfo set [2, if (_pictureEntryName == "") then {""} else {getText (_configPath >> _pictureEntryName)}]; - _cachedItemInfo set [0, getText (_configPath >> "displayName")]; - //if _pictureEntryName is empty then this item has no Icons. (Faces) - _cachedItemInfo set [1, if (_pictureEntryName isEqualTo "") then {""} else {getText (_configPath >> _pictureEntryName)}]; - - //get name of DLC - private _dlcName = ""; - private _addons = configsourceaddonlist _configPath; - if (_addons isNotEqualTo []) then { - private _mods = configsourcemodlist (configfile >> "CfgPatches" >> _addons select 0); - if (_mods isNotEqualTo []) then { - _dlcName = _mods select 0; - }; - }; + // Get name of DLC + private _dlcName = _configPath call EFUNC(common,getAddon); if (_dlcName != "") then { - _cachedItemInfo set [2, (modParams [_dlcName,["logo"]]) param [0,""]];//mod picture + _cachedItemInfo set [3, (modParams [_dlcName, ["logo"]]) param [0, ""]]; // Mod picture } else { - _cachedItemInfo set [2, ""];//mod picture - _cachedItemInfo set [3, 0];//mod ID + _cachedItemInfo set [3, ""]; // Mod picture }; - _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; -}; -_cachedItemInfo params ["_displayName", "_itemPicture", "_modPicture"]; + // Store in cache + GVAR(addListBoxItemCache) set [_itemInfo, _cachedItemInfo]; +}; -private _lbAdd = _ctrlPanel lbAdd _displayName; +_cachedItemInfo params ["_className", "_displayName", "_itemPicture", "_modPicture"]; +private _lbAdd = _ctrlPanel lbAdd _displayName; _ctrlPanel lbSetData [_lbAdd, _className]; _ctrlPanel lbSetPicture [_lbAdd, _itemPicture]; -_ctrlPanel lbSetPictureRight [_lbAdd,["",_modPicture] select (GVAR(enableModIcons))]; +_ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; diff --git a/addons/arsenal/functions/fnc_addRightPanelButton.sqf b/addons/arsenal/functions/fnc_addRightPanelButton.sqf index 7d4ecd0d988..3db4db286e2 100644 --- a/addons/arsenal/functions/fnc_addRightPanelButton.sqf +++ b/addons/arsenal/functions/fnc_addRightPanelButton.sqf @@ -1,18 +1,17 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: shukari, Schwaggot - * Adds a right panel button for uniforms, vests and backpacks with - * defined misc items. + * Author: shukari, Schwaggot, johnb43 + * Adds a right panel button for uniforms, vests and backpacks with defined misc. items. * * Arguments: - * 0: items only misc items - * 1: tooltip (Optional) - * 2: picture path (Optional) - * 3: override a specific button (0-9) (Optional) + * 0: Items (only misc. items) + * 1: Tooltip (Optional) + * 2: Picture path (Optional) + * 3: Override a specific button (0-9) (Optional) * * Return Value: - * successful: number of the slot (0-9); error: -1 + * Successful: Number of the slot (0-9); Error: -1 * * Example: * [["ACE_bloodIV_500", "ACE_Banana"], "MedicalStuff", "\z\ace\addons\arsenal\data\iconCustom.paa", 5] call ace_arsenal_fnc_addRightPanelButton @@ -23,33 +22,40 @@ params [["_items", [], [[]]], ["_tooltip", "", [""]], ["_picture", QPATHTOF(data\iconCustom.paa), [""]], ["_override", -1, [0]]]; if (isNil QGVAR(customRightPanelButtons)) then { - GVAR(customRightPanelButtons) = []; + GVAR(customRightPanelButtons) = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]; }; -private _position = count GVAR(customRightPanelButtons); +private _position = -1; -if (_override != -1 && {_override >= 0} && {_override <= 9}) then { +// See if override is valid +if (_override >= 0 && {_override <= 9}) then { _position = _override; } else { + // Try to find an empty spot private _emptyPos = GVAR(customRightPanelButtons) findIf {isNil "_x"}; + if (_emptyPos != -1) then { _position = _emptyPos; }; }; -private _return = -1; -if (_position >= 0 && _position <= 9) then { - private _cfgWeapons = configFile >> "CfgWeapons"; - _items = _items select { - private _configItemInfo = _cfgWeapons >> _x >> "ItemInfo"; +// If spot not found, return error +if (_position < 0 || {_position > 9}) exitWith { + -1 +}; - _x isKindOf ["CBA_MiscItem", _cfgWeapons] && {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} || - {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} - }; +// If spot found, add items and return position +private _cfgWeapons = configFile >> "CfgWeapons"; +private _configItemInfo = ""; - _return = _position; - GVAR(customRightPanelButtons) set [_position, [_items apply {toLower _x}, _picture, _tooltip]]; +_items = _items select { + _configItemInfo = _cfgWeapons >> _x >> "ItemInfo"; + + _x isKindOf ["CBA_MiscItem", _cfgWeapons] && {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} || + {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} }; -_return +GVAR(customRightPanelButtons) set [_position, [_items apply {_x call EFUNC(common,getConfigName)}, _picture, _tooltip]]; + +_position diff --git a/addons/arsenal/functions/fnc_addSort.sqf b/addons/arsenal/functions/fnc_addSort.sqf index 9ecdcc03d2e..4063ca1a4fa 100644 --- a/addons/arsenal/functions/fnc_addSort.sqf +++ b/addons/arsenal/functions/fnc_addSort.sqf @@ -4,16 +4,16 @@ * 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 + * 0: Tabs to add sort to + * 0.1: Left Tab Indexes + * 0.2: Right Tab Indexes + * 1: Sort class (a unique string for each algorithm) + * 2: Title * 3: Algorithm - * 4: Condition (Optional) + * 4: Condition (Optional) * * Return Value: - * 0: Array of IDs (ARRAY of STRINGS) + * 0: Array of IDs * * Example: * [[[0, 1], []], "fireRateSort", "Sort by fire rate", { @@ -23,11 +23,11 @@ * * { * _fireRate pushBackUnique (getNumber (_itemCfg >> _x >> "reloadTime")); - * } foreach _fireModes; + * } forEach _fireModes; * * _fireRate sort true; * _fireRate param [0, 0] - * }] call ACE_arsenal_fnc_addSort; + * }] call ace_arsenal_fnc_addSort; * * Public: Yes */ @@ -35,7 +35,7 @@ params [ ["_tabs", [[], []], [[]], 2], ["_class", "", [""]], - ["_displayName", "", [""]], + ["_title", "", [""]], ["_statement", {}, [{}]], ["_condition", {true}, [{}]] ]; @@ -51,6 +51,7 @@ 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 ""]; @@ -59,7 +60,7 @@ private _fnc_addToTabs = { } forEach _tabsToAddTo; }; -_finalArray = ["", _displayName, _statement, _condition]; +_finalArray = ["", _title, _statement, _condition]; if (_leftTabs isNotEqualTo []) then { [GVAR(sortListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf index ac13e976992..eb400c9a0b5 100644 --- a/addons/arsenal/functions/fnc_addStat.sqf +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -4,32 +4,33 @@ * 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) + * 0: Tabs to add the stat to + * 0.1 Left tab indexes + * 0.2 Right tab indexes + * 1: Stat class (a unique string for each stat) + * 2: Config entries to pass + * 3: Title + * 4: Show bar / show text bools (Optional) + * 4.1 Show bar + * 4.2 Show text + * 5: Array of statements + * 5.1 Bar code + * 5.2 Text code + * 5.3 Condition code + * 6: Priority (Optional) * * Return Value: - * 0: Array of IDs (ARRAY of STRINGS) + * 0: Array of IDs * * Example: - * [[[0,1,2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { + * [[[0, 1, 2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { params ["_statsArray", "_itemCfg"]; getNumber (_itemCfg >> _statsArray select 0) - }, {true}]] call ACE_arsenal_fnc_addStat + }, {true}]] call ace_arsenal_fnc_addStat * * Public: Yes */ + params [ ["_tabs", [[], []], [[]], 2], ["_class", "", [""]], @@ -45,7 +46,10 @@ _tabs params [ ["_rightTabs", [], [[]]] ]; -_bools params [["_showBar", false, [false]], ["_showText", false, [false]]]; +_bools params [ + ["_showBar", false, [false]], + ["_showText", false, [false]] +]; _statements params [ ["_barStatement", {}, [{}]], @@ -59,15 +63,14 @@ 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 { + 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; @@ -78,21 +81,21 @@ private _fnc_addToTabs = { if (count _x < 5) exitWith { (_currentTab select _forEachIndex) append [_arrayToSave]; }; - } foreach _currentTab; + } forEach _currentTab; } else { _currentTab pushBack [_arrayToSave]; }; }; - } foreach _tabsToAddTo; + } forEach _tabsToAddTo; }; private _finalArray = ["", _stats, _title, [_showBar, _showText], [_barStatement, _textStatement, _condition], _priority]; -if (count _leftTabs > 0) then { +if (_leftTabs isNotEqualTo []) then { [GVAR(statsListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; }; -if (count _rightTabs > 0) then { +if (_rightTabs isNotEqualTo []) then { [GVAR(statsListRightPanel), _rightTabs, "R", 1] call _fnc_addToTabs; }; diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index 1d9a7826036..71d185ca33c 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, Dedmen + * Author: Alganthe, Dedmen, johnb43 * Add virtual items to the provided target. * * Arguments: * 0: Target * 1: Items - * 2: Add globally + * 2: Add globally (Optional) * * Return Value: * None @@ -21,206 +21,203 @@ params [["_object", objNull, [objNull]], ["_items", [], [true, []]], ["_global", false, [false]]]; -if (_object == objNull) exitWith {}; -if (_items isEqualType [] && {count _items == 0}) exitWith {}; +if (isNull _object || {_items isEqualTo []}) exitWith {}; -private _cargo = _object getVariable [QGVAR(virtualItems), [ - [[], [], []], // Weapons 0, primary, secondary, handgun - [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod - [ ], // Magazines 2 - [ ], // Headgear 3 - [ ], // Uniform 4 - [ ], // Vest 5 - [ ], // Backpacks 6 - [ ], // Goggles 7 - [ ], // NVGs 8 - [ ], // Binoculars 9 - [ ], // Map 10 - [ ], // Compass 11 - [ ], // Radio slot 12 - [ ], // Watch slot 13 - [ ], // Comms slot 14 - [ ], // WeaponThrow 15 - [ ], // WeaponPut 16 - [ ] // InventoryItems 17 -]]; - -private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in variable for perf improvement +private _cargo = _object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]; +// If passed arguement is "true", add all items if (_items isEqualType true) then { if (_items) then { + private _weapons = _cargo select IDX_VIRT_WEAPONS; + private _weaponAttachments = _cargo select IDX_VIRT_ATTACHMENTS; private _configItems = uiNamespace getVariable QGVAR(configItems); + // Add onto existing items, in case some items that were already added aren't available by default in the arsenal { (_x select 0) append (_x select 1); - (_x select 2) set [(_x select 3), (_x select 0) arrayIntersect (_x select 0)]; + (_x select 2) set [_x select 3, (_x select 0) arrayIntersect (_x select 0)]; } forEach [ - [(_cargo select 0 select 0),(_configItems select 0 select 0), _cargo select 0, 0], - [(_cargo select 0 select 1),(_configItems select 0 select 1), _cargo select 0, 1], - [(_cargo select 0 select 2),(_configItems select 0 select 2), _cargo select 0, 2], - [(_cargo select 1 select 0),(_configItems select 1 select 0), _cargo select 1, 0], - [(_cargo select 1 select 1),(_configItems select 1 select 1), _cargo select 1, 1], - [(_cargo select 1 select 2),(_configItems select 1 select 2), _cargo select 1, 2], - [(_cargo select 1 select 3),(_configItems select 1 select 3), _cargo select 1, 3] + [_weapons select IDX_VIRT_PRIMARY_WEAPONS, _configItems select IDX_VIRT_WEAPONS select IDX_VIRT_PRIMARY_WEAPONS, _weapons, IDX_VIRT_PRIMARY_WEAPONS], + [_weapons select IDX_VIRT_SECONDARY_WEAPONS, _configItems select IDX_VIRT_WEAPONS select IDX_VIRT_SECONDARY_WEAPONS, _weapons, IDX_VIRT_SECONDARY_WEAPONS], + [_weapons select IDX_VIRT_HANDGUN_WEAPONS, _configItems select IDX_VIRT_WEAPONS select IDX_VIRT_HANDGUN_WEAPONS, _weapons, IDX_VIRT_HANDGUN_WEAPONS], + [_weaponAttachments select IDX_VIRT_OPTICS_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_OPTICS_ATTACHMENTS, _weaponAttachments, IDX_VIRT_OPTICS_ATTACHMENTS], + [_weaponAttachments select IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _weaponAttachments, IDX_VIRT_FLASHLIGHT_ATTACHMENTS], + [_weaponAttachments select IDX_VIRT_MUZZLE_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_MUZZLE_ATTACHMENTS, _weaponAttachments, IDX_VIRT_MUZZLE_ATTACHMENTS], + [_weaponAttachments select IDX_VIRT_BIPOD_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_BIPOD_ATTACHMENTS, _weaponAttachments, IDX_VIRT_BIPOD_ATTACHMENTS] ]; - for "_index" from 2 to 17 do { + // Add onto existing items, in case some items that were already added aren't available by default in the arsenal + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { (_cargo select _index) append (_configItems select _index); _cargo set [_index, (_cargo select _index) arrayIntersect (_cargo select _index)]; }; }; - } else { + // Make sure all items are in string form, then convert to config case (non-existent items return "") + _items = (_items select {_x isEqualType ""}) apply {_x call EFUNC(common,getConfigName)}; + + // Remove any invalid/non-existing items + _items = _items - [""]; + + private _configItemInfo = ""; + private _simulationType = ""; + private _hasItemInfo = false; + + private _cfgWeapons = configFile >> "CfgWeapons"; + private _cfgMagazines = configFile >> "CfgMagazines"; + private _cfgVehicles = configFile >> "CfgVehicles"; + private _cfgGlasses = configFile >> "CfgGlasses"; + + private _grenadeList = uiNamespace getVariable [QGVAR(grenadeCache), []]; + private _putList = uiNamespace getVariable [QGVAR(putCache), []]; + + // _items can contain classNames with scope < 2, which aren't necessarily in the arsenal cache { - if (_x isEqualType "") then { - private _configItemInfo = _configCfgWeapons >> _x >> "ItemInfo"; - private _simulationType = getText (_configCfgWeapons >> _x >> "simulation"); - switch true do { - case (isClass (_configCfgWeapons >> _x)): { - switch true do { - /* Weapon acc */ - case ( - isClass (_configItemInfo) && - {(getNumber (_configItemInfo >> "type")) in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} && - {!(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])} - ): { - switch (getNumber (_configItemInfo >> "type")) do { - case TYPE_OPTICS: { - (_cargo select 1) select 0 pushBackUnique _x; - }; - case TYPE_FLASHLIGHT: { - (_cargo select 1) select 1 pushBackUnique _x; - }; - case TYPE_MUZZLE: { - (_cargo select 1) select 2 pushBackUnique _x; - }; - case TYPE_BIPOD: { - (_cargo select 1) select 3 pushBackUnique _x; - }; + _configItemInfo = _cfgWeapons >> _x >> "ItemInfo"; + _simulationType = getText (_cfgWeapons >> _x >> "simulation"); + _hasItemInfo = isClass (_configItemInfo); + + switch (true) do { + case (isClass (_cfgWeapons >> _x)): { + switch (true) do { + // Weapon attachments + case ( + _hasItemInfo && + {getNumber (_configItemInfo >> "type") in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]} && + {!(_x isKindOf ["CBA_MiscItem", _cfgWeapons])} + ): { + switch (getNumber (_configItemInfo >> "type")) do { + case TYPE_OPTICS: { + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS) pushBackUnique _x; }; - }; - /* Headgear */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_HEADGEAR}): { - (_cargo select 3) pushBackUnique _x; - }; - /* Uniform */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_UNIFORM}): { - (_cargo select 4) pushBackUnique _x; - }; - /* Vest */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_VEST}): { - (_cargo select 5) pushBackUnique _x; - }; - /* NVgs */ - case (_simulationType == "NVGoggles"): { - (_cargo select 8) pushBackUnique _x; - }; - /* Binos */ - case (_simulationType == "Binocular" || - {(_simulationType == 'Weapon') && {(getNumber (_configCfgWeapons >> _x >> 'type') == TYPE_BINOCULAR_AND_NVG)}}): { - (_cargo select 9) pushBackUnique _x; - }; - /* Map */ - case (_simulationType == "ItemMap"): { - (_cargo select 10) pushBackUnique _x; - }; - /* Compass */ - case (_simulationType == "ItemCompass"): { - (_cargo select 11) pushBackUnique _x; - }; - /* Radio */ - case (_simulationType == "ItemRadio"): { - (_cargo select 12) pushBackUnique _x; - }; - /* Watch */ - case (_simulationType == "ItemWatch"): { - (_cargo select 13) pushBackUnique _x; - }; - /* GPS */ - case (_simulationType == "ItemGPS"): { - (_cargo select 14) pushBackUnique _x; - }; - /* UAV terminals */ - case (isClass (_configItemInfo) && - {getNumber (_configItemInfo >> "type") == TYPE_UAV_TERMINAL}): { - (_cargo select 14) pushBackUnique _x; - }; - /* Weapon, at the bottom to avoid adding binos */ - case (isClass (_configCfgWeapons >> _x >> "WeaponSlotsInfo") && - {getNumber (_configCfgWeapons >> _x >> 'type') != TYPE_BINOCULAR_AND_NVG}): { - switch (getNumber (_configCfgWeapons >> _x >> "type")) do { - case TYPE_WEAPON_PRIMARY: { - (_cargo select 0) select 0 pushBackUnique ([_x] call bis_fnc_baseWeapon); - }; - case TYPE_WEAPON_HANDGUN: { - (_cargo select 0) select 2 pushBackUnique ([_x] call bis_fnc_baseWeapon); - }; - case TYPE_WEAPON_SECONDARY: { - (_cargo select 0) select 1 pushBackUnique ([_x] call bis_fnc_baseWeapon); - }; + case TYPE_FLASHLIGHT: { + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) pushBackUnique _x; + }; + case TYPE_MUZZLE: { + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS) pushBackUnique _x; + }; + case TYPE_BIPOD: { + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS) pushBackUnique _x; }; - }; - /* Misc items */ - case ( - isClass (_configItemInfo) && - ((getNumber (_configItemInfo >> "type")) in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && - {(_x isKindOf ["CBA_MiscItem", (_configCfgWeapons)])}) || - {(getNumber (_configItemInfo >> "type")) in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {(getText (_configCfgWeapons >> _x >> "simulation")) == "ItemMineDetector"} - ): { - (_cargo select 17) pushBackUnique _x; }; }; - }; - case (isClass (configFile >> "CfgMagazines" >> _x)): { - // Lists to check against - private _grenadeList = []; - { - _grenadeList append getArray (_configCfgWeapons >> "Throw" >> _x >> "magazines"); - false - } count getArray (_configCfgWeapons >> "Throw" >> "muzzles"); - - private _putList = []; - { - _putList append getArray (_configCfgWeapons >> "Put" >> _x >> "magazines"); - false - } count getArray (_configCfgWeapons >> "Put" >> "muzzles"); - - // Check what the magazine actually is - switch true do { - // Rifle, handgun, secondary weapons mags - case ( - ((getNumber (configFile >> "CfgMagazines" >> _x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW,TYPE_MAGAZINE_SECONDARY_AND_PUT,1536,TYPE_MAGAZINE_HANDGUN_AND_GL]) || - {(getNumber (configFile >> "CfgMagazines" >> _x >> QGVAR(hide))) == -1}) && - {!(_x in _grenadeList)} && - {!(_x in _putList)} - ): { - (_cargo select 2) pushBackUnique _x; - }; - // Grenades - case (_x in _grenadeList): { - (_cargo select 15) pushBackUnique _x; - }; - // Put - case (_x in _putList): { - (_cargo select 16) pushBackUnique _x; + // Headgear + case ( + _hasItemInfo && + {getNumber (_configItemInfo >> "type") == TYPE_HEADGEAR} + ): { + (_cargo select IDX_VIRT_HEADGEAR) pushBackUnique _x; + }; + // Uniforms + case ( + _hasItemInfo && + {getNumber (_configItemInfo >> "type") == TYPE_UNIFORM} + ): { + (_cargo select IDX_VIRT_UNIFORM) pushBackUnique _x; + }; + // Vests + case ( + _hasItemInfo && + {getNumber (_configItemInfo >> "type") == TYPE_VEST} + ): { + (_cargo select IDX_VIRT_VEST) pushBackUnique _x; + }; + // NVGs + case (_simulationType == "NVGoggles"): { + (_cargo select IDX_VIRT_NVG) pushBackUnique _x; + }; + // Binoculars + case ( + _simulationType == "Binocular" || + {_simulationType == "Weapon" && {getNumber (_cfgWeapons >> _x >> "type") == TYPE_BINOCULAR_AND_NVG}} + ): { + (_cargo select IDX_VIRT_BINO) pushBackUnique _x; + }; + // Maps + case (_simulationType == "ItemMap"): { + (_cargo select IDX_VIRT_MAP) pushBackUnique _x; + }; + // Compasses + case (_simulationType == "ItemCompass"): { + (_cargo select IDX_VIRT_COMPASS) pushBackUnique _x; + }; + // Radios + case (_simulationType == "ItemRadio"): { + (_cargo select IDX_VIRT_RADIO) pushBackUnique _x; + }; + // Watches + case (_simulationType == "ItemWatch"): { + (_cargo select IDX_VIRT_WATCH) pushBackUnique _x; + }; + // GPS and UAV Terminals + case ( + _simulationType == "ItemGPS" || + {_hasItemInfo && + {getNumber (_configItemInfo >> "type") == TYPE_UAV_TERMINAL}} + ): { + (_cargo select IDX_VIRT_COMMS) pushBackUnique _x; + }; + // Weapons, at the bottom to avoid adding binos + case ( + isClass (_cfgWeapons >> _x >> "WeaponSlotsInfo") && + {getNumber (_cfgWeapons >> _x >> "type") != TYPE_BINOCULAR_AND_NVG} + ): { + switch (getNumber (_cfgWeapons >> _x >> "type")) do { + case TYPE_WEAPON_PRIMARY: { + ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_x call EFUNC(common,baseWeapon)); + }; + case TYPE_WEAPON_HANDGUN: { + ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_x call EFUNC(common,baseWeapon)); + }; + case TYPE_WEAPON_SECONDARY: { + ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_x call EFUNC(common,baseWeapon)); + }; }; }; + // Misc. items + case ( + _hasItemInfo && + {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && + {_x isKindOf ["CBA_MiscItem", _cfgWeapons]}} || + {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} + ): { + (_cargo select IDX_VIRT_MISC_ITEMS) pushBackUnique _x; + }; }; - case (isClass (configFile >> "CfgVehicles" >> _x)): { - if (getNumber (configFile >> "CfgVehicles" >> _x >> "isBackpack") == 1) then { - (_cargo select 6) pushBackUnique _x; + }; + case (isClass (_cfgMagazines >> _x)): { + // Check what type the magazine actually is + switch (true) do { + // Grenades + case (_x in _grenadeList): { + (_cargo select IDX_VIRT_GRENADES) pushBackUnique _x; + }; + // Explosives + case (_x in _putList): { + (_cargo select IDX_VIRT_EXPLOSIVES) pushBackUnique _x; + }; + // Primary, handgun & secondary weapon magazines, and magazines that are forced with "ace_arsenal_hide = -1" + case ( + getNumber (_cfgMagazines >> _x >> QGVAR(hide)) == -1 || + {getNumber (_cfgMagazines >> _x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL]} + ): { + (_cargo select IDX_VIRT_ITEMS_ALL) pushBackUnique _x; }; }; - case (isClass (configFile >> "CfgGlasses" >> _x)): { - (_cargo select 7) pushBackUnique _x; + }; + // Backpacks + case (isClass (_cfgVehicles >> _x)): { + if (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1) then { + (_cargo select IDX_VIRT_BACKPACK) pushBackUnique _x; }; }; + // Goggles + case (isClass (_cfgGlasses >> _x)): { + (_cargo select IDX_VIRT_GOGGLES) pushBackUnique _x; + }; }; - } foreach _items; + } forEach _items; }; _object setVariable [QGVAR(virtualItems), _cargo, _global]; diff --git a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf index 0b8e3f25577..1dbb8bc208c 100644 --- a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf +++ b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: mharis001 + * Author: mharis001, johnb43 * Adds compatible attachments or magazines for all weapons in 3DEN attribute. * * Arguments: @@ -23,51 +23,36 @@ private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CAT // Exit if selected category is not attachments or magazines if !(_category in [4, 5, 6, 7, 8]) exitWith {}; -private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); +private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems"]; // Get list of all weapons in attribute items -(_configItems select 0) params ["_primaryWeapons", "_secondaryWeapons", "_handgunWeapons"]; -private _attributeWeapons = _attributeItems select {_x in _primaryWeapons || {_x in _secondaryWeapons} || {_x in _handgunWeapons}}; +private _attributeWeapons = _attributeItems arrayIntersect (flatten (_configItems select IDX_VIRT_WEAPONS)); // Add compatible attachments or magazines to attribute -private _cfgWeapons = configFile >> "CfgWeapons"; private _itemsToAdd = []; if (_category == 8) then { - private _magazineGroups = uiNamespace getVariable QGVAR(magazineGroups); - private _cfgMagazines = configFile >> "CfgMagazines"; - + // Get all compatible magazines for weapons { - private _weaponConfig = _cfgWeapons >> _x; - - { - private _muzzleConfig = if (_x == "this") then {_weaponConfig} else {_weaponConfig >> _x}; - - // Only add existent magazines and ensure correct classname case - private _magazines = getArray (_muzzleConfig >> "magazines") select {isClass (_cfgMagazines >> _x)}; - _magazines = _magazines apply {configName (_cfgMagazines >> _x)}; - _itemsToAdd append _magazines; - - { - _itemsToAdd append (_magazineGroups get (toLower _x)); - } forEach getArray (_muzzleConfig >> "magazineWell"); - } forEach getArray (_weaponConfig >> "muzzles"); + _itemsToAdd append (compatibleMagazines _x); } forEach _attributeWeapons; + + _itemsToAdd = _itemsToAdd arrayIntersect (_configItems select IDX_VIRT_ITEMS_ALL); } else { private _attachmentCategory = _category - 4; private _filter = ["optic", "pointer", "muzzle", "bipod"] select _attachmentCategory; + // CBA_fnc_compatibleItems returns config case sensitive names { _itemsToAdd append ([_x, _filter] call CBA_fnc_compatibleItems); } forEach _attributeWeapons; - // Only add items with scope of 2 and ensure correct classname case - _itemsToAdd = _itemsToAdd select {getNumber (_cfgWeapons >> _x >> "scope") == 2}; - _itemsToAdd = _itemsToAdd apply {configName (_cfgWeapons >> _x)}; + _itemsToAdd = _itemsToAdd arrayIntersect (flatten (_configItems select IDX_VIRT_ATTACHMENTS)); }; +// Only take items that can be found by default in the arsenal _attributeItems append _itemsToAdd; _attributeValue set [0, _attributeItems arrayIntersect _attributeItems]; diff --git a/addons/arsenal/functions/fnc_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf index 12611bbdeb8..17183c4c554 100644 --- a/addons/arsenal/functions/fnc_attributeAddItems.sqf +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: mharis001 - * Populates 3DEN attribute listbox with items of given category. + * Author: mharis001, johnb43 + * Populates 3DEN's ace arsenal attribute listbox with items of given category. * * Arguments: * 0: Attribute controls group @@ -20,43 +20,47 @@ params ["_controlsGroup"]; private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; private _filter = toLower ctrlText (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR); -private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); +private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; +_attributeValue params ["_attributeItems", "_attributeMode"]; + TRACE_3("Populating list",_category,_filter,_attributeValue); -_attributeValue params ["_attributeItems", "_attributeMode"]; private _modeSymbol = [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode; // Clear listbox private _listbox = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST; lnbClear _listbox; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgGlasses = configFile >> "CfgGlasses"; + // Exit with current items (no specific category) if (_category == -1) exitWith { + private _config = configNull; + private _displayName = ""; + private _picture = ""; + private _index = -1; + { // Get appropriate config for each item (different since items can be from any category) - private _config = switch (true) do { - case (_x in (_configItems select 2)); - case (_x in (_configItems select 15)); - case (_x in (_configItems select 16)): { - configFile >> "CfgMagazines" >> _x; - }; - case (_x in (_configItems select 6)): { - configFile >> "CfgVehicles" >> _x; - }; - case (_x in (_configItems select 7)): { - configFile >> "CfgGlasses" >> _x; - }; - default { - configFile >> "CfgWeapons" >> _x; - }; + _config = switch (true) do { + case (_x in (_configItems select IDX_VIRT_ITEMS_ALL)); + case (_x in (_configItems select IDX_VIRT_GRENADES)); + case (_x in (_configItems select IDX_VIRT_EXPLOSIVES)): {_cfgMagazines >> _x}; + case (_x in (_configItems select IDX_VIRT_BACKPACK)): {_cfgVehicles >> _x}; + case (_x in (_configItems select IDX_VIRT_GOGGLES)): {_cfgGlasses >> _x}; + default {_cfgWeapons >> _x}; }; + _displayName = getText (_config >> "displayName"); + // Add item if not filtered - private _displayName = getText (_config >> "displayName"); - if (toLower _displayName find _filter > -1) then { - private _picture = getText (_config >> "picture"); - private _index = _listbox lnbAddRow ["", _displayName, _modeSymbol]; + if (_filter in (toLower _displayName) || {_filter in (toLower _x)}) then { + _picture = getText (_config >> "picture"); + _index = _listbox lnbAddRow ["", _displayName, _modeSymbol]; _listbox lnbSetData [[_index, 1], _x]; _listbox lnbSetPicture [[_index, 0], _picture]; _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; @@ -68,12 +72,15 @@ if (_category == -1) exitWith { // Get list of category items private _categoryItems = switch (true) do { + // Weapons case (_category < 3): { - _configItems select 0 select _category; + _configItems select IDX_VIRT_WEAPONS select _category; }; + // Weapon attachments case (_category < 7): { - _configItems select 1 select (_category - 3); + _configItems select IDX_VIRT_ATTACHMENTS select (_category - 3); }; + // Other default { _configItems select (_category - 5); }; @@ -81,28 +88,27 @@ private _categoryItems = switch (true) do { // Get config for current category private _config = switch (true) do { - case (_category in [7, 20, 21]): { - configFile >> "CfgMagazines"; - }; - case (_category == 11): { - configFile >> "CfgVehicles"; - }; - case (_category == 12): { - configFile >> "CfgGlasses"; - }; - default { - configFile >> "CfgWeapons"; - }; + case (_category in [7, 20, 21]): {_cfgMagazines}; + case (_category == 11): {_cfgVehicles}; + case (_category == 12): {_cfgGlasses}; + default {_cfgWeapons}; }; +private _displayName = ""; +private _picture = ""; +private _symbol = SYMBOL_ITEM_NONE; +private _alpha = 0; +private _index = -1; + // Populate listbox with category items { + _displayName = getText (_config >> _x >> "displayName"); + // Add item if not filtered - private _displayName = getText (_config >> _x >> "displayName"); - if (toLower _displayName find _filter > -1) then { - private _picture = getText (_config >> _x >> "picture"); - private _symbol = SYMBOL_ITEM_NONE; - private _alpha = 0.5; + if (_filter in (toLower _displayName) || {_filter in (toLower _x)}) then { + _picture = getText (_config >> _x >> "picture"); + _symbol = SYMBOL_ITEM_NONE; + _alpha = 0.5; // Change symbol and alpha if item already selected if (_x in _attributeItems) then { @@ -110,7 +116,7 @@ private _config = switch (true) do { _alpha = 1; }; - private _index = _listbox lnbAddRow ["", _displayName, _symbol]; + _index = _listbox lnbAddRow ["", _displayName, _symbol]; _listbox lnbSetData [[_index, 1], _x]; _listbox lnbSetPicture [[_index, 0], _picture]; _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; diff --git a/addons/arsenal/functions/fnc_attributeCategory.sqf b/addons/arsenal/functions/fnc_attributeCategory.sqf index e0c0468f8ab..990226ef3e5 100644 --- a/addons/arsenal/functions/fnc_attributeCategory.sqf +++ b/addons/arsenal/functions/fnc_attributeCategory.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" /* * Author: mharis001 - * Handles changing the category in 3DEN attribute. + * Handles changing the category in 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group diff --git a/addons/arsenal/functions/fnc_attributeClear.sqf b/addons/arsenal/functions/fnc_attributeClear.sqf index a0a8cb070d7..992c645a4ec 100644 --- a/addons/arsenal/functions/fnc_attributeClear.sqf +++ b/addons/arsenal/functions/fnc_attributeClear.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" /* * Author: mharis001 - * Clears all items from current category in 3DEN attribute. + * Clears all items from current category in 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -27,18 +27,22 @@ if (_category == -1) then { _attributeValue set [0, []]; } else { // Find category items and remove from list - private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); + private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; private _categoryItems = switch (true) do { + // Weapons case (_category < 3): { - _configItems select 0 select _category; + _configItems select IDX_VIRT_WEAPONS select _category; }; + // Weapon attachments case (_category < 7): { - _configItems select 1 select (_category - 3); + _configItems select IDX_VIRT_ATTACHMENTS select (_category - 3); }; + // Other default { _configItems select (_category - 5); }; }; + _attributeValue set [0, (_attributeValue select 0) - _categoryItems]; }; diff --git a/addons/arsenal/functions/fnc_attributeDblClick.sqf b/addons/arsenal/functions/fnc_attributeDblClick.sqf index 6cb9314bcfc..185de7206e3 100644 --- a/addons/arsenal/functions/fnc_attributeDblClick.sqf +++ b/addons/arsenal/functions/fnc_attributeDblClick.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: mharis001 - * Handles double clicking a row in 3DEN attribute listbox. + * Handles double clicking a row in 3DEN's ace arsenal attribute listbox. * * Arguments: * 0: Listbox diff --git a/addons/arsenal/functions/fnc_attributeImport.sqf b/addons/arsenal/functions/fnc_attributeImport.sqf index ec56df4b569..fdc3dd8c5f5 100644 --- a/addons/arsenal/functions/fnc_attributeImport.sqf +++ b/addons/arsenal/functions/fnc_attributeImport.sqf @@ -1,7 +1,8 @@ #include "script_component.hpp" +#include "..\defines.hpp" /* * Author: mharis001 - * Handles importing items list from clipboard into 3DEN attribute. + * Handles importing items list from clipboard into 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -15,8 +16,6 @@ * Public: No */ -params ["_controlsGroup"]; - private _importList = call compile copyFromClipboard; // Verify import list is in correct format @@ -24,23 +23,36 @@ if (isNil "_importList" || {!(_importList isEqualType [])} || {!(_importList isE playSound ["3DEN_notificationWarning", true]; }; -// Ensure imported items are in scanned config array and classname case is correct -private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]); +params ["_controlsGroup"]; + +// Convert all items to config case +_importList = _importList apply {_x call EFUNC(common,getConfigName)}; + +// Remove any invalid/non-existing items +_importList = _importList - [""]; + +// Ensure imported items are in scanned config array +private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; private _configItemsFlat = _configItems select [2, 16]; -_configItemsFlat append (_configItems select 0); -_configItemsFlat append (_configItems select 1); +_configItemsFlat append (_configItems select IDX_VIRT_WEAPONS); +_configItemsFlat append (_configItems select IDX_VIRT_ATTACHMENTS); private _filteredList = []; +private _intersection = []; { - private _item = _x; - { - private _index = _x findIf {_x == _item}; - if (_index > -1) then { - _filteredList pushBackUnique (_x select _index); - }; - } forEach _configItemsFlat; -} forEach _importList; + // Find common entries + _intersection = _x arrayIntersect _importList; + + _filteredList append _intersection; + + //////////////////////// Is this necessary/wanted? + // Remove found entries, to reduce input array size + _importList = _importList - _intersection; + + // Quit if nothing is left to import + if (_importList isEqualTo []) exitWith {}; +} forEach _configItemsFlat; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue set [0, _filteredList]; diff --git a/addons/arsenal/functions/fnc_attributeInit.sqf b/addons/arsenal/functions/fnc_attributeInit.sqf index 8c1556fcd6c..e0891cdf530 100644 --- a/addons/arsenal/functions/fnc_attributeInit.sqf +++ b/addons/arsenal/functions/fnc_attributeInit.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: mharis001 - * Initializes the objects 3DEN attribute at scenario start. + * Initializes the objects 3DEN's ace arsenal attribute at scenario start. * * Arguments: * 0: Attribute target @@ -28,6 +28,7 @@ if (_mode > 0) then { [{ [{ params ["_object", "_items"]; + [_object, _items, true] call FUNC(removeVirtualItems); }, _this] call CBA_fnc_execNextFrame; }, [_object, _items]] call CBA_fnc_execNextFrame; diff --git a/addons/arsenal/functions/fnc_attributeKeyDown.sqf b/addons/arsenal/functions/fnc_attributeKeyDown.sqf index 300ab9f6c5e..9406454d8c1 100644 --- a/addons/arsenal/functions/fnc_attributeKeyDown.sqf +++ b/addons/arsenal/functions/fnc_attributeKeyDown.sqf @@ -2,7 +2,7 @@ #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* * Author: mharis001 - * Handles keyboard input for the 3DEN attribute. + * Handles keyboard input for the 3DEN's ace arsenal attribute. * * Arguments: * 0: Display @@ -21,18 +21,23 @@ params ["_display", "_keyCode"]; TRACE_2("Attribute key down",_display,_keyCode); // Exit if attribute is not in focus -private _controlsGroup = uiNamespace getVariable QGVAR(attributeFocus); -if (isNil "_controlsGroup") exitWith {false}; +private _controlsGroup = uiNamespace getVariable [QGVAR(attributeFocus), controlNull]; + +if (isNull _controlsGroup) exitWith {false}; switch (_keyCode) do { + // Unselect item case DIK_LEFT; case DIK_NUMPADMINUS: { [_controlsGroup, false] call FUNC(attributeSelect); + true }; + // Select item case DIK_RIGHT; case DIK_NUMPADPLUS: { [_controlsGroup, true] call FUNC(attributeSelect); + true }; default {false}; diff --git a/addons/arsenal/functions/fnc_attributeLoad.sqf b/addons/arsenal/functions/fnc_attributeLoad.sqf index 355d5e113a8..97b044c5f89 100644 --- a/addons/arsenal/functions/fnc_attributeLoad.sqf +++ b/addons/arsenal/functions/fnc_attributeLoad.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" /* * Author: mharis001 - * Initializes the 3DEN attribute. + * Initializes the 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group @@ -23,10 +23,8 @@ TRACE_1("Initializing 3DEN attribute",_value); // Store working attribute value uiNamespace setVariable [QGVAR(attributeValue), _value]; -// Add keyDown EH to display -// Does not work properly when added to controls group -private _display = ctrlParent _controlsGroup; -_display displayAddEventHandler ["KeyDown", {call FUNC(attributeKeyDown)}]; +// Add keyDown EH to display; Does not work properly when added to controls group +(ctrlParent _controlsGroup) displayAddEventHandler ["KeyDown", {call FUNC(attributeKeyDown)}]; // Handle selected mode if (_value select 1 > 0) then { diff --git a/addons/arsenal/functions/fnc_attributeMode.sqf b/addons/arsenal/functions/fnc_attributeMode.sqf index 807fea2ec43..400d63049c2 100644 --- a/addons/arsenal/functions/fnc_attributeMode.sqf +++ b/addons/arsenal/functions/fnc_attributeMode.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" /* * Author: mharis001 - * Handles changing the mode in 3DEN attribute. + * Handles changing the mode in 3DEN's ace arsenal attribute. * * Arguments: * 0: Attribute controls group diff --git a/addons/arsenal/functions/fnc_attributeSelect.sqf b/addons/arsenal/functions/fnc_attributeSelect.sqf index 7af0ecc7645..3edf209d012 100644 --- a/addons/arsenal/functions/fnc_attributeSelect.sqf +++ b/addons/arsenal/functions/fnc_attributeSelect.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" /* * Author: mharis001 - * Handles adding/removing an item from 3DEN attribute list. + * Handles adding/removing an item from 3DEN's ace arsenal attribute list. * * Arguments: * 0: Attribute controls group @@ -28,11 +28,12 @@ TRACE_2("Handling item selection",_itemClassname,_addItem); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems", "_attributeMode"]; -private _findItem = _attributeItems find _itemClassname; +private _itemIndex = _attributeItems find _itemClassname; // Add item if not already in list -if (_addItem && {_findItem < 0}) exitWith { +if (_addItem && {_itemIndex == -1}) exitWith { _attributeItems pushBack _itemClassname; + // Change symbol and increase alpha _listbox lnbSetText [[_currentRow, 2], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode]; _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 1]]; @@ -40,8 +41,9 @@ if (_addItem && {_findItem < 0}) exitWith { }; // Remove item if in list -if (!_addItem && {_findItem > -1}) exitWith { - _attributeItems deleteAt _findItem; +if (!_addItem && {_itemIndex != -1}) exitWith { + _attributeItems deleteAt _itemIndex; + // Change symbol and reduce alpha _listbox lnbSetText [[_currentRow, 2], SYMBOL_ITEM_NONE]; _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 0.5]]; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index cc8cdf45bfe..e03fed40d18 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -1,12 +1,12 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Add or remove item(s) when the + or - button is pressed in the right panel. * * Arguments: * 0: Arsenal display - * 1: Add or remove (-1: remove, 1: Add) + * 1: Add or remove (-1: Remove, 1: Add) * * Return Value: * None @@ -16,77 +16,92 @@ params ["_display", "_addOrRemove"]; -private _load = 0; -private _maxLoad = ""; -private _items = []; -private _ctrlList = (_display displayCtrl IDC_rightTabContentListnBox); +_addOrRemove = _addOrRemove > 0; + +private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; private _lnbCurSel = lnbCurSelRow _ctrlList; -private _item = _ctrlList lnbData [_lnbCurSel, 0]; -if ((_ctrlList lnbValue [_lnbCurSel, 2]) == 1 && {_addOrRemove == 1}) exitWith {}; +// If item is unique, don't allow adding more +if (_addOrRemove && {(_ctrlList lnbValue [_lnbCurSel, 2]) == 1}) exitWith {}; -// Update item count and currentItems array -switch GVAR(currentLeftPanel) do { +private _containerItems = []; +private _item = _ctrlList lnbData [_lnbCurSel, 0]; - case IDC_buttonUniform : { - if (_addOrRemove > 0) then { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) addItemToUniform _item; - }; - } else { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) removeItemFromUniform _item; - }; +// Update item count and currentItems array & get relevant container +private _container = switch (GVAR(currentLeftPanel)) do { + // Uniform + case IDC_buttonUniform: { + if (_addOrRemove) then { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) addItemToUniform _item; }; + } else { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) removeItemFromUniform _item; + }; + }; - _load = loadUniform GVAR(center); - _maxLoad = gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass"); - _items = uniformItems GVAR(center); - GVAR(currentItems) set [15 ,_items]; - }; + _containerItems = uniformItems GVAR(center); - case IDC_buttonVest : { - if (_addOrRemove > 0) then { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) addItemToVest _item; - }; - } else { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) removeItemFromVest _item; - }; - }; + // Update currentItems + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_UNIFORM) param [1, []]]; + + // Update load bar + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); - _load = loadVest GVAR(center); - _maxLoad = gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass"); - _items = vestItems GVAR(center); - GVAR(currentItems) set [16,_items]; + uniformContainer GVAR(center) }; + // Vest + case IDC_buttonVest: { + if (_addOrRemove) then { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) addItemToVest _item; + }; + } else { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) removeItemFromVest _item; + }; + }; - case IDC_buttonBackpack : { - if (_addOrRemove > 0) then { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) addItemToBackpack _item; - }; - } else { - for "_count" from 1 to ([1, 5] select (GVAR(shiftState))) do { - GVAR(center) removeItemFromBackpack _item; - }; + _containerItems = vestItems GVAR(center); + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_VEST) param [1, []]]; + + // Update load bar + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); + + vestContainer GVAR(center) + }; + // Backpack + case IDC_buttonBackpack: { + if (_addOrRemove) then { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) addItemToBackpack _item; + }; + } else { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) removeItemFromBackpack _item; }; + }; - _load = loadBackpack GVAR(center); - _maxLoad = backpack GVAR(center); - _items = backpackItems GVAR(center); - GVAR(currentItems) set [17,_items]; + _containerItems = backpackItems GVAR(center); + + // Update currentItems + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_BACKPACK) param [1, []]]; + + // Update load bar + (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); + + backpackContainer GVAR(center) }; }; -// Update progress bar status, weight info -private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; -_loadIndicatorBarCtrl progressSetPosition _load; - -private _value = {_x == _item} count _items; -_ctrlList lnbSetText [[_lnbCurSel, 2],str _value]; +// Find out how many items of that type there are and update the number displayed +_ctrlList lnbSetText [[_lnbCurSel, 2], str ({_x == _item} count _containerItems)]; +//////////////////// Return NUMBER, as it did before or return BOOL, as the doc says is should ? [QGVAR(cargoChanged), [_display, _item, _addOrRemove, GVAR(shiftState)]] call CBA_fnc_localEvent; -[_ctrlList, _maxLoad] call FUNC(updateRightPanel); +// Refresh availibility of items based on space remaining in container +[_ctrlList, _container, _containerItems isNotEqualTo []] call FUNC(updateRightPanel); diff --git a/addons/arsenal/functions/fnc_buttonClearAll.sqf b/addons/arsenal/functions/fnc_buttonClearAll.sqf index 8e1d70d6ebf..555a7143791 100644 --- a/addons/arsenal/functions/fnc_buttonClearAll.sqf +++ b/addons/arsenal/functions/fnc_buttonClearAll.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Clear the current container. * * Arguments: @@ -15,48 +15,47 @@ params ["_display"]; -// Clear container -switch (GVAR(currentLeftPanel)) do { +// Clear chosen container, reset currentItems for that container and get relevant container +private _container = switch (GVAR(currentLeftPanel)) do { + // Uniform case IDC_buttonUniform: { - {GVAR(center) removeItemFromUniform _x} foreach (uniformItems GVAR(center)); - GVAR(currentItems) set [15, []]; + { + GVAR(center) removeItemFromUniform _x; + } forEach (vestItems GVAR(center)); + + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, []]; + + uniformContainer GVAR(center) }; + // Vest case IDC_buttonVest: { - {GVAR(center) removeItemFromVest _x} foreach (vestItems GVAR(center)); - GVAR(currentItems) set [16, []]; + { + GVAR(center) removeItemFromVest _x; + } forEach (vestItems GVAR(center)); + + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, []]; + + vestContainer GVAR(center) }; + // Backpack case IDC_buttonBackpack: { - {GVAR(center) removeItemFromBackpack _x} foreach (backpackItems GVAR(center)); - GVAR(currentItems) set [17, []]; + clearAllItemsFromBackpack GVAR(center); + + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, []]; + + backpackContainer GVAR(center) }; }; // Clear number of owned items private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; -for "_l" from 0 to (lbSize _ctrlList - 1) do { - _ctrlList lnbSetText [[_l, 2], str 0]; +for "_lbIndex" from 0 to (lbSize _ctrlList) - 1 do { + _ctrlList lnbSetText [[_lbIndex, 2], "0"]; }; -private _removeAllCtrl = _display displayCtrl IDC_buttonRemoveAll; -_removeAllCtrl ctrlSetFade 1; -_removeAllCtrl ctrlCommit FADE_DELAY; - // Update load bar -private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; -_loadIndicatorBarCtrl progressSetPosition 0; - -private _maxLoad = switch (GVAR(currentLeftPanel)) do { - case IDC_buttonUniform: { - gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonVest: { - gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonBackpack: { - backpack GVAR(center) - }; -}; +(_display displayCtrl IDC_loadIndicatorBar) progressSetPosition 0; -private _control = _display displayCtrl IDC_rightTabContentListnBox; -[_control, _maxLoad] call FUNC(updateRightPanel); +// Refresh availibility of items based on space remaining in container +[_ctrlList, _container, false] call FUNC(updateRightPanel); diff --git a/addons/arsenal/functions/fnc_buttonExport.sqf b/addons/arsenal/functions/fnc_buttonExport.sqf index 3ff75be8245..167b6c4e57a 100644 --- a/addons/arsenal/functions/fnc_buttonExport.sqf +++ b/addons/arsenal/functions/fnc_buttonExport.sqf @@ -15,39 +15,41 @@ params ["_display"]; if (GVAR(shiftState)) then { - if (isNil QGVAR(defaultLoadoutsList) || {GVAR(defaultLoadoutsList) isEqualTo []}) exitWith { - [_display, localize LSTRING(exportDefaultError)] call FUNC(message); + [_display, LLSTRING(exportDefaultError)] call FUNC(message); }; + // Export default loadout list private _listLength = count GVAR(defaultLoadoutsList); - for "_index" from -1 to _listLength do { - switch true do { + for "_index" from -1 to _listLength do { + switch (true) do { + // Beginning case (_index == -1): { "ace_clipboard" callExtension (format ["[%1", endl]); }; - + // End case (_index == _listLength): { "ace_clipboard" callExtension "];"; }; - + // Rest default { - "ace_clipboard" callExtension ([" ",str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""); + "ace_clipboard" callExtension ([" ", str (GVAR(defaultLoadoutsList) select _index), [",", ""] select (_index == _listLength - 1), endl] joinString ""); }; }; }; "ace_clipboard" callExtension "--COMPLETE--"; - [_display, localize LSTRING(exportDefault)] call FUNC(message); + [_display, LLSTRING(exportDefault)] call FUNC(message); } else { + // Export singular loadout + private _export = str (GVAR(center) call FUNC(getLoadout)); - private _export = str ([GVAR(center)] call FUNC(getLoadout)); "ace_clipboard" callExtension (_export + ";"); "ace_clipboard" callExtension "--COMPLETE--"; - [_display, localize LSTRING(exportCurrent)] call FUNC(message); + [_display, LLSTRING(exportCurrent)] call FUNC(message); }; [QGVAR(loadoutExported), [_display, GVAR(shiftState)]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf index 23e4f7d081f..1f149c5f3a6 100644 --- a/addons/arsenal/functions/fnc_buttonHide.sqf +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -16,12 +16,13 @@ params ["_display"]; private _showToggle = !ctrlShown (_display displayCtrl IDC_menuBar); +private _ctrl = controlNull; { - private _ctrl = _display displayctrl _x; - _ctrl ctrlshow _showToggle; - _ctrl ctrlcommit 0.15; -} foreach [ + _ctrl = _display displayCtrl _x; + _ctrl ctrlShow _showToggle; + _ctrl ctrlCommit FADE_DELAY; +} forEach [ IDC_blockLeftFrame, IDC_blockLeftBackground, IDC_blockRightFrame, diff --git a/addons/arsenal/functions/fnc_buttonImport.sqf b/addons/arsenal/functions/fnc_buttonImport.sqf index 4bc633874c2..eea1370f9bf 100644 --- a/addons/arsenal/functions/fnc_buttonImport.sqf +++ b/addons/arsenal/functions/fnc_buttonImport.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Import loadout / default loadouts list from clipboard. * * Arguments: @@ -15,102 +15,72 @@ params ["_display"]; -private _data = call (compile copyFromClipboard); +// Can be either a singular loadout or an array of loadouts +private _extendedLoadout = call compile copyFromClipboard; -if (isNil "_data" || {!(_data isEqualType [])}) exitWith { - [_display, localize LSTRING(importFormatError)] call FUNC(message); +// If error, exit +if (isNil "_extendedLoadout" || {!(_extendedLoadout isEqualType [])}) exitWith { + [_display, LLSTRING(importFormatError)] call FUNC(message); }; if (GVAR(shiftState) && {is3DEN}) then { - + // Supports CBA extended loadout or getUnitLoadout arrays { if ( - count _x == 2 && - {_x select 0 isEqualType ""} && - {_x select 0 != ""} && - {_x select 1 isEqualType []} && - {count (_x select 1) == 10} + count _x == 2 && + {(_x select 0) isEqualType ""} && + {(_x select 0) != ""} && + {(_x select 1) isEqualType []} && + {count (_x select 1) in [2, 10]} ) then { _x call FUNC(addDefaultLoadout); }; - } foreach _data; + } forEach _extendedLoadout; - [_display, localize LSTRING(importedDefault)] call FUNC(message); - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + [_display, LLSTRING(importedDefault)] call FUNC(message); + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; } else { - private _count = count _data; - if (_count == 10 || { _count == 2 }) then { - [GVAR(center), _data] call CBA_fnc_setLoadout; - - GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; - for "_index" from 0 to 15 do { - switch (_index) do { - case 0; - case 1; - case 2:{ - GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; - }; - case 3; - case 4; - case 5; - case 6; - case 7; - case 8; - case 9: { - GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; - - }; - case 10: { - {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); - }; - case 11: { - {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); - }; - case 12: { - {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); - }; - case 13: { - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; - }; - case 14: { - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; - }; - case 15: { - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; - }; - }; - }; - + // If _extendedLoadout is in getUnitLoadout array, change into CBA extended loadout array + if (count _extendedLoadout == 10) then { + _extendedLoadout = [_extendedLoadout, createHashMap]; + }; - { - private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); - private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch", "itemgps"] find (tolower _simulationType)); + // Check if CBA extended loadout array + if ((count _extendedLoadout) == 2) then { + [GVAR(center), _extendedLoadout] call CBA_fnc_setLoadout; - GVAR(currentItems) set [_index, _x]; - } foreach (assignedItems GVAR(center)); + // Update current item list + call FUNC(updateCurrentItemsList); + // This takes care of items that aren't available in the arsenal (either wrong tab or arsenal doesn't have it whitelisted) call FUNC(updateUniqueItemsList); + _extendedLoadout params ["_loadout", "_extendedInfo"]; + // Reapply insignia - if (QGVAR(insignia) in _loadout#1) then { - GVAR(currentInsignia) = _loadout#1 getOrDefault [QGVAR(insignia), ""]; + if (QGVAR(insignia) in _extendedInfo) then { + GVAR(currentInsignia) = _extendedInfo getOrDefault [QGVAR(insignia), ""]; } else { - [GVAR(center), ""] call bis_fnc_setUnitInsignia; - [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; - if (QGVAR(face) in _loadout#1) then { - GVAR(currentFace) = _loadout#1 getOrDefault [QGVAR(face), GVAR(currentFace)]; + // Save face + if (QGVAR(face) in _extendedInfo) then { + GVAR(currentFace) = _extendedInfo getOrDefault [QGVAR(face), GVAR(currentFace)]; }; - if (QGVAR(voice) in _loadout#1) then { - GVAR(currentVoice) = _loadout#1 getOrDefault [QGVAR(voice), GVAR(currentVoice)]; + + // Save voice + if (QGVAR(voice) in _extendedInfo) then { + GVAR(currentVoice) = _extendedInfo getOrDefault [QGVAR(voice), GVAR(currentVoice)]; }; + // Fill left panel [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); - [_display, localize LSTRING(importedCurrent)] call FUNC(message); + [_display, LLSTRING(importedCurrent)] call FUNC(message); }; }; -[QGVAR(loadoutImported), [_display, (GVAR(shiftState) && {is3DEN})]] call CBA_fnc_localEvent; +[QGVAR(loadoutImported), [_display, GVAR(shiftState) && {is3DEN}]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf index 7ca972fde25..511b8216bea 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsDelete.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Delete / unshare loadout currently selected. * * Arguments: @@ -22,35 +22,39 @@ private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; private _contentPanelCursSel = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_contentPanelCursSel, 1]; +// If loadout is local or default if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { - + // Find loadout and delete from list if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { - GVAR(defaultLoadoutsList) deleteAt (GVAR(defaultLoadoutsList) find ((GVAR(defaultLoadoutsList) select {_x select 0 == _loadoutName}) select 0)); - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + GVAR(defaultLoadoutsList) deleteAt (GVAR(defaultLoadoutsList) findIf {(_x select 0) == _loadoutName}); + + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; } else { - private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; - _data deleteAt (_data find ((_data select {_x select 0 == _loadoutName}) select 0)); + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + + _data deleteAt (_data findIf {(_x select 0) == _loadoutName}); }; _contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), nil]; _contentPanelCtrl lnbDeleteRow _contentPanelCursSel; - _contentPanelCtrl lnbSetCurSelRow (_contentPanelCursSel); + _contentPanelCtrl lnbSetCurSelRow _contentPanelCursSel; + + [findDisplay IDD_ace_arsenal, [LLSTRING(loadoutDeleted), _loadoutName] joinString " "] call FUNC(message); - [(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutDeleted), _loadoutName] joinString " "] call FUNC(message); [QGVAR(onLoadoutDelete), [_loadoutName]] call CBA_fnc_localEvent; } else { - + // If loadout is shared private _profileName = profileName; // GVAR(center) could be a remote unit private _loadoutVar = _profileName + _loadoutName; - private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); + private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable [QGVAR(sharedLoadoutsVars), []]; GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars - [_loadoutVar], true]; _contentPanelCtrl lnbDeleteRow _contentPanelCursSel; - _contentPanelCtrl lnbSetCurSelRow (_contentPanelCursSel); + _contentPanelCtrl lnbSetCurSelRow _contentPanelCursSel; - [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; + [findDisplay IDD_ace_arsenal, [LLSTRING(loadoutUnshared), _loadoutName] joinString " "] call FUNC(message); - [(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutUnshared), _loadoutName] joinString " "] call FUNC(message); + [QGVAR(loadoutUnshared), [_contentPanelCtrl, _profileName, _loadoutName]] call CBA_fnc_remoteEvent; }; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf index 40e84b01f00..9b09c0d66c6 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Load selected loadout. * * Arguments: @@ -22,90 +22,48 @@ private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; private _curSel = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_curSel, 1]; -private _loadout = switch GVAR(currentLoadoutsTab) do { - +private _extendedLoadout = switch (GVAR(currentLoadoutsTab)) do { + // Local and default loadouts case IDC_buttonMyLoadouts; - case IDC_buttonDefaultLoadouts:{ + case IDC_buttonDefaultLoadouts: { (_contentPanelCtrl getVariable _loadoutName + str GVAR(currentLoadoutsTab)) select 0 }; - - case IDC_buttonSharedLoadouts:{ + // Shared loadouts + case IDC_buttonSharedLoadouts: { (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_curSel, 0]) + (_contentPanelCtrl lnbText [_curSel, 1]))) select 2 }; }; -[GVAR(center), _loadout, true] call CBA_fnc_setLoadout; - -GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; -for "_index" from 0 to 15 do { - switch (_index) do { - case 0; - case 1; - case 2:{ - GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; - }; - case 3; - case 4; - case 5; - case 6; - case 7; - case 8; - case 9: { - GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; - - }; - case 10: { - {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); - }; - case 11: { - {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); - }; - case 12: { - {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); - }; - case 13: { - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; - }; - case 14: { - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; - }; - case 15: { - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; - }; - }; -}; -{ - private _simulationType = getText (configFile >> "CfgWeapons" >> _x >> "simulation"); - - if (_simulationType != "NVGoggles") then { - if (_simulationType == "ItemGps" || _simulationType == "Weapon") then { - GVAR(currentItems) set [14, _x]; - } else { +// Apply loadout to unit +[GVAR(center), _extendedLoadout, true] call CBA_fnc_setLoadout; - private _index = 10 + (["itemmap", "itemcompass", "itemradio", "itemwatch"] find (tolower _simulationType)); - GVAR(currentItems) set [_index, _x]; - }; - }; -} forEach (assignedItems GVAR(center)); +// Update current item list +call FUNC(updateCurrentItemsList); +// This takes care of items that aren't available in the arsenal (either wrong tab or arsenal doesn't have it whitelisted) call FUNC(updateUniqueItemsList); +_extendedLoadout params ["_loadout", "_extendedInfo"]; + // Reapply insignia -if (QGVAR(insignia) in _loadout#1) then { - GVAR(currentInsignia) = _loadout#1 getOrDefault [QGVAR(insignia), ""]; +if (QGVAR(insignia) in _extendedInfo) then { + GVAR(currentInsignia) = _extendedInfo getOrDefault [QGVAR(insignia), ""]; } else { - [GVAR(center), ""] call bis_fnc_setUnitInsignia; - [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; -if (QGVAR(face) in _loadout#1) then { - GVAR(currentFace) = _loadout#1 getOrDefault [QGVAR(face), GVAR(currentFace)]; +// Update current face if necessary +if (QGVAR(face) in _extendedInfo) then { + GVAR(currentFace) = _extendedInfo getOrDefault [QGVAR(face), GVAR(currentFace)]; }; -if (QGVAR(voice) in _loadout#1) then { - GVAR(currentVoice) = _loadout#1 getOrDefault [QGVAR(voice), GVAR(currentVoice)]; + +// Update voice face if necessary +if (QGVAR(voice) in _extendedInfo) then { + GVAR(currentVoice) = _extendedInfo getOrDefault [QGVAR(voice), GVAR(currentVoice)]; }; -[(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutLoaded), _loadoutName] joinString " "] call FUNC(message); +[findDisplay IDD_ace_arsenal, [LLSTRING(loadoutLoaded), _loadoutName] joinString " "] call FUNC(message); -[QGVAR(onLoadoutLoad), [_loadout#0, _loadoutName]] call CBA_fnc_localEvent; -[QGVAR(onLoadoutLoadExtended), [_loadout, _loadoutName]] call CBA_fnc_localEvent; +[QGVAR(onLoadoutLoad), [_loadout, _loadoutName]] call CBA_fnc_localEvent; +[QGVAR(onLoadoutLoadExtended), [_extendedLoadout, _loadoutName]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf index bcb230d3aee..5c321a45e97 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Rename selected loadout. * * Arguments: @@ -23,49 +23,45 @@ private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; private _curSelRow = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_curSelRow, 1]; -private _editBoxCtrl = _display displayCtrl IDC_textEditBox; -private _editBoxContent = ctrlText _editBoxCtrl; +// Get text from text edit box +private _editBoxContent = ctrlText (_display displayCtrl IDC_textEditBox); -private _data = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts && {is3DEN}); -private _similarLoadouts = _data select {_x select 0 == _editBoxContent}; +// If it's the exact same name, don't do anything +if (_editBoxContent isEqualTo _loadoutName) exitWith {}; -if (count _similarLoadouts > 0) exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(renameExistError)] call FUNC(message); +private _data = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}); + +// If there is a loadout with a similar name and it's not chosen to be renamed, don't rename and exit +if (_editBoxContent != _loadoutName && {_data findIf {(_x select 0) == _editBoxContent} != -1}) exitWith { + [findDisplay IDD_ace_arsenal, LLSTRING(renameExistError)] call FUNC(message); }; // Update loadout info in profile / 3DEN and list namespaces -private _loadoutToRename = (_data select {_x select 0 == _loadoutName}) select 0; -(_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; +private _loadoutIndex = _data findIf {(_x select 0) == _loadoutName}; -_data set [_data find _loadoutToRename, [_editBoxContent, (_loadoutToRename select 1)]]; -_contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), nil]; -_contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]]; +// Set new name +(_data select _loadoutIndex) set [0, _editBoxContent]; -// Add new row -_contentPanelCtrl lnbDeleteRow _curSelRow; -private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; +if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; +}; -_extendedLoadout params ["_loadout"]; -ADD_LOADOUTS_LIST_PICTURES +private _currentLoadoutsTab = str GVAR(currentLoadoutsTab); -if (_nullItemsAmount > 0) then { +_contentPanelCtrl setVariable [_editBoxContent + _currentLoadoutsTab, _contentPanelCtrl getVariable [_loadoutName + _currentLoadoutsTab, []]]; +_contentPanelCtrl setVariable [_loadoutName + _currentLoadoutsTab, nil]; - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; -} else { +// Update the current row's loadout name +_contentPanelCtrl lnbSetText [[_curSelRow, 1], _editBoxContent]; - if (_unavailableItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; - }; -}; - -// Sort and select the current row +// Sort alphabetically _contentPanelCtrl lnbSort [1, false]; -for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; -}; -if (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}) then { - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; +// Select the newly renamed loadout +for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex; + }; }; -[(findDisplay IDD_ace_arsenal), [_loadoutName, localize LSTRING(loadoutRenamed) ,_editBoxContent] joinString " "] call FUNC(message); +[findDisplay IDD_ace_arsenal, [_loadoutName, LLSTRING(loadoutRenamed), _editBoxContent] joinString " "] call FUNC(message); diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf index d4d5b00a4b4..c25ef21a7c6 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Save selected loadout. * * Arguments: @@ -21,239 +21,117 @@ if !(ctrlEnabled _control) exitWith {}; private _editBoxCtrl = _display displayCtrl IDC_textEditBox; private _editBoxContent = ctrlText _editBoxCtrl; +// If no name given, throw error if (_editBoxContent == "") exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(saveEmptyNameBox)] call FUNC(message); + [findDisplay IDD_ace_arsenal, LLSTRING(saveEmptyNameBox)] call FUNC(message); }; -private _data = [+(profileNamespace getVariable [QGVAR(saved_loadouts),[]]), +(GVAR(defaultLoadoutsList))] select (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts && {is3DEN}); -private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; -private _cursSelRow = lnbCurSelRow _contentPanelCtrl; - -private _loadoutName = _contentPanelCtrl lnbText [_cursSelRow, 1]; -private _curSelLoadout = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; -private _extendedLoadout = GVAR(center) call FUNC(getLoadout); -private _loadout = _loadout select 0; - -private _loadoutIndex = _data findIf {(_x select 0) == _editBoxContent}; -private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); +// Get shared loadouts +private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable [QGVAR(sharedLoadoutsVars), []]; // Make sure the loadout isn't yours (public tab) or being shared (my loadouts tab) -private _similarSharedLoadout = (profileName + _editBoxContent) in _sharedLoadoutsVars; -if ((_contentPanelCtrl lnbText [_cursSelRow, 0]) == profileName) exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(saveAuthorError)] call FUNC(message); -}; - -if (_similarSharedLoadout) exitWith { - [(findDisplay IDD_ace_arsenal), localize LSTRING(saveSharedError)] call FUNC(message); +if ((profileName + _editBoxContent) in _sharedLoadoutsVars) exitWith { + [findDisplay IDD_ace_arsenal, LLSTRING(saveSharedError)] call FUNC(message); }; -switch (GVAR(currentLoadoutsTab)) do { - case IDC_buttonMyLoadouts:{ +private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +private _curSelRow = lnbCurSelRow _contentPanelCtrl; - for "_dataIndex" from 0 to 10 do { - switch (_dataIndex) do { +if ((_contentPanelCtrl lnbText [_curSelRow, 0]) == profileName) exitWith { + [findDisplay IDD_ace_arsenal, LLSTRING(saveAuthorError)] call FUNC(message); +}; - case 0; - case 1; - case 2; - case 8: { - if (count (_loadout select _dataIndex) > 0) then { +// Get currently selected loadout name & loadout +private _loadoutName = _contentPanelCtrl lnbText [_curSelRow, 1]; +private _curSelLoadout = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; - private _weapon = (_loadout select _dataIndex) select 0; - if (_weapon != "") then { +// Get unit's current loadout +private _extendedLoadout = GVAR(center) call FUNC(getLoadout); +_extendedLoadout params ["_loadout"]; - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_loadout select _dataIndex) set [0, _baseWeapon]; - }; - }; - }; - }; +private _loadouts = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}); +private _loadoutIndex = _loadouts findIf {(_x select 0) == _editBoxContent}; - case 3; - case 4; - case 5: { - if (count (_loadout select _dataIndex) > 0) then { - private _containerContents = (_loadout select _dataIndex) select 1; - - if (count _containerContents > 0) then { - - { - if (count _x == 2) then { - - if ((_x select 0) isEqualType "") then { - - private _item = (_x select 0); - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - _x set [0, _uniqueBaseCfgText]; - }; - }; - } else { - private _weapon = (_x select 0) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_x select 0)set [0, _baseWeapon]; - }; - }; - }; - }; - } foreach _containerContents; - }; - }; - }; +// Return what loadout was saved +private _savedLoadout = switch (GVAR(currentLoadoutsTab)) do { + // Local loadouts tab + case IDC_buttonMyLoadouts: { + // If saved to default loadout + if (GVAR(shiftState) && {is3DEN} && {_loadoutName != ""} && {_curSelRow != -1} && {_loadoutIndex != -1}) then { + private _defaultLoadoutsSearch = GVAR(defaultLoadoutsList) findIf {(_x select 0) == _loadoutName}; - case 9: { - for "_subIndex" from 0 to 4 do { - private _item = (_loadout select _dataIndex) select _subIndex; + if (_defaultLoadoutsSearch == -1) then { + _loadoutIndex = GVAR(defaultLoadoutsList) pushBack [_loadoutName, _curSelLoadout]; + } else { + GVAR(defaultLoadoutsList) set [_defaultLoadoutsSearch, [_loadoutName, _curSelLoadout]]; + }; - if (_item != "") then { + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { + _curSelLoadout + } else { + // Replace unique items with their bases and replace weapons with their base weapons + _loadout = [_loadout] call FUNC(replaceUniqueItemsLoadout); - (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; - }; - }; - }; - }; - }; - }; + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; - if (GVAR(shiftState) && {is3DEN} && {_loadoutName isNotEqualTo ""} && {_cursSelRow != -1} && {_loadoutIndex isNotEqualTo -1}) exitwith { - private _defaultLoadoutsSearch = GVAR(defaultLoadoutsList) findIf {(_x select 0) == _loadoutName}; - if (_defaultLoadoutsSearch isEqualto -1) then { - GVAR(defaultLoadoutsList) pushBack [_loadoutName, _curSelLoadout]; + // Add or overwrite loadout in loadout storage + if (_loadoutIndex == -1) then { + _loadoutIndex = _data pushBack [_editBoxContent, _extendedLoadout]; } else { - GVAR(defaultLoadoutsList) set [_defaultLoadoutsSearch , [ _loadoutName, _curSelLoadout]]; + _data set [_loadoutIndex, [_editBoxContent, _extendedLoadout]]; }; - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; - }; - if (_loadoutIndex isEqualto -1) then { - _data pushBack [_editBoxContent, _extendedLoadout]; - } else { - _data set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _extendedLoadout]]; - }; + // Refresh loadout list; Delete previous loadout row + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; + }; - // Delete "old" loadout row - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbDeleteRow _i}; - }; + private _newRow = _contentPanelCtrl lnbAddRow ["", _editBoxContent]; + private _cfgWeapons = configFile >> "CfgWeapons"; - private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + ADD_LOADOUTS_LIST_PICTURES - ADD_LOADOUTS_LIST_PICTURES + _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout] call FUNC(verifyLoadout)]; - _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout] call FUNC(verifyLoadout)]; + _contentPanelCtrl lnbSort [1, false]; - _contentPanelCtrl lnbSort [1, false]; + // Select newly saved loadout + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex; + }; + }; - // Select newly saved loadout - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + _extendedLoadout }; - - profileNamespace setVariable [QGVAR(saved_loadouts), _data]; }; - - case IDC_buttonDefaultLoadouts:{ - + // Default loadouts tab + case IDC_buttonDefaultLoadouts: { if (is3DEN) then { + // Replace unique items with their bases and replace weapons with their base weapons + _loadout = [_loadout] call FUNC(replaceUniqueItemsLoadout); - private _loadoutIndex = _data findIf {(_x select 0) == _editBoxContent}; - - for "_dataIndex" from 0 to 10 do { - switch (_dataIndex) do { - - case 0; - case 1; - case 2; - case 8: { - if (count (_loadout select _dataIndex) > 0) then { - - private _weapon = (_loadout select _dataIndex) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_loadout select _dataIndex) set [0, _baseWeapon]; - }; - }; - }; - }; - - case 3; - case 4; - case 5: { - if (count (_loadout select _dataIndex) > 0) then { - private _containerContents = (_loadout select _dataIndex) select 1; - - if (count _containerContents > 0) then { - - { - if (count _x == 2) then { - - if ((_x select 0) isEqualType "") then { - - private _item = (_x select 0); - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - _x set [0, _uniqueBaseCfgText]; - }; - }; - } else { - private _weapon = (_x select 0) select 0; - if (_weapon != "") then { - - private _baseWeapon = _weapon call BIS_fnc_baseWeapon; - if (_weapon != _baseWeapon) then { - (_x select 0)set [0, _baseWeapon]; - }; - }; - }; - }; - } foreach _containerContents; - }; - }; - }; - - case 9: { - for "_subIndex" from 0 to 4 do { - private _item = (_loadout select _dataIndex) select _subIndex; - - if (_item != "") then { - - private _uniqueBaseCfgText = getText (configFile >> "CfgWeapons" >> _item >> "ace_arsenal_uniqueBase"); - if (_uniqueBaseCfgText != "") then { - - (_loadout select _dataIndex) set [_subIndex, _uniqueBaseCfgText]; - }; - }; - }; - }; - }; - }; - + // Add or overwrite loadout in loadout storage if (_loadoutIndex == -1) then { - GVAR(defaultLoadoutsList) pushBack [_editBoxContent, _extendedLoadout]; + _loadoutIndex = GVAR(defaultLoadoutsList) pushBack [_editBoxContent, _extendedLoadout]; } else { - GVAR(defaultLoadoutsList) set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _extendedLoadout]]; + GVAR(defaultLoadoutsList) set [_loadoutIndex, [_editBoxContent, _extendedLoadout]]; }; - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbDeleteRow _i}; + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + + // Refresh loadout list; Delete previous loadout row + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; }; - private _newRow = _contentPanelCtrl lnbAddRow ["",_editBoxContent]; + private _newRow = _contentPanelCtrl lnbAddRow ["", _editBoxContent]; + private _cfgWeapons = configFile >> "CfgWeapons"; ADD_LOADOUTS_LIST_PICTURES @@ -262,39 +140,46 @@ switch (GVAR(currentLoadoutsTab)) do { _contentPanelCtrl lnbSort [1, false]; // Select newly saved loadout - for '_i' from 0 to (((lnbsize _contentPanelCtrl) select 0) - 1) do { - if ((_contentPanelCtrl lnbText [_i, 1]) == _editBoxContent) exitwith {_contentPanelCtrl lnbSetCurSelRow _i}; + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _editBoxContent) exitWith { + _contentPanelCtrl lnbSetCurSelRow _lbIndex; + }; }; - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; + _extendedLoadout } else { + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + // Add or overwrite loadout in loadout storage if (_loadoutIndex == -1) then { - _data pushBack [_editBoxContent, _curSelLoadout]; + _loadoutIndex = _data pushBack [_editBoxContent, _curSelLoadout]; } else { - _data set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _curSelLoadout]]; + _data set [_loadoutIndex, [_editBoxContent, _curSelLoadout]]; _contentPanelCtrl setVariable [_editBoxContent + str IDC_buttonMyLoadouts, [_curSelLoadout] call FUNC(verifyLoadout)]; }; - profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + _curSelLoadout }; }; + // Shared loadouts tab + case IDC_buttonSharedLoadouts: { + _loadout = (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_curSelRow, 0]) + (_contentPanelCtrl lnbText [_curSelRow, 1]))) select 2; - case IDC_buttonSharedLoadouts :{ - - _loadout = (GVAR(sharedLoadoutsNamespace) getVariable ((_contentPanelCtrl lnbText [_cursSelRow, 0]) + (_contentPanelCtrl lnbText [_cursSelRow, 1]))) select 2; + private _data = profileNamespace getVariable [QGVAR(saved_loadouts), []]; + // Add or overwrite loadout in loadout storage if (_loadoutIndex == -1) then { - _data pushBack [_editBoxContent, _loadout]; + _loadoutIndex = _data pushBack [_editBoxContent, _loadout]; } else { - _data set [_loadoutIndex, [[_editBoxContent, _loadoutName] select (_loadoutName isEqualTo _editBoxContent), _loadout]]; + _data set [_loadoutIndex, [_editBoxContent, _loadout]]; _contentPanelCtrl setVariable [_editBoxContent + str IDC_buttonMyLoadouts, [_loadout] call FUNC(verifyLoadout)]; }; - profileNamespace setVariable [QGVAR(saved_loadouts), _data]; + _loadout }; }; -[(findDisplay IDD_ace_arsenal), [localize LSTRING(loadoutSaved), _editBoxContent] joinString " "] call FUNC(message); -private _savedLoadout = (_data select {_x select 0 == _editBoxContent}) select 0; -[QGVAR(onLoadoutSave), [_data find _savedLoadout, _savedLoadout#0]] call CBA_fnc_localEvent; -[QGVAR(onLoadoutSaveExtended), [_data find _savedLoadout, _savedLoadout]] call CBA_fnc_localEvent; + +[findDisplay IDD_ace_arsenal, [LLSTRING(loadoutSaved), _editBoxContent] joinString " "] call FUNC(message); + +[QGVAR(onLoadoutSave), [_loadoutIndex, _savedLoadout select 0]] call CBA_fnc_localEvent; +[QGVAR(onLoadoutSaveExtended), [_loadoutIndex, _savedLoadout]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf index a9a1dd9d086..459d9879d6a 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsShare.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Share selected loadout. * * Arguments: @@ -23,33 +23,33 @@ private _contentPanelCursSel = lnbCurSelRow _contentPanelCtrl; private _loadoutName = _contentPanelCtrl lnbText [_contentPanelCursSel, 1]; private _profileName = profileName; // GVAR(center) could be a remote unit private _loadoutVar = _profileName + _loadoutName; -private _sharedLoadoutsVars = +(GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars)); +private _sharedLoadoutsVars = +(GVAR(sharedLoadoutsNamespace) getVariable [QGVAR(sharedLoadoutsVars), []]); -private _loadoutIndex = _sharedLoadoutsVars find _loadoutVar; private _loadoutData = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; -// Loadout set to private -if (_loadoutIndex > -1) then { +if (_loadoutVar in _sharedLoadoutsVars) then { + // Loadout is shared, set to private GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars - [_loadoutVar], true]; _contentPanelCtrl lnbSetPicture [[_contentPanelCursSel, 0], QPATHTOF(data\iconPublicBlank.paa)]; _contentPanelCtrl lnbSetValue [[_contentPanelCursSel, 0], 0]; - [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; -// Loadout set to public + [QGVAR(loadoutUnshared), [_contentPanelCtrl, _profileName, _loadoutName]] call CBA_fnc_remoteEvent; } else { - GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, [_profileName ,_loadoutName , _loadoutData], true]; + // Loadout is private, set to shared + GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, [_profileName, _loadoutName, _loadoutData], true]; _sharedLoadoutsVars pushBackUnique _loadoutVar; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsVars), _sharedLoadoutsVars, true]; _contentPanelCtrl lnbSetPicture [[_contentPanelCursSel, 0], QPATHTOF(data\iconPublic.paa)]; _contentPanelCtrl lnbSetValue [[_contentPanelCursSel, 0], 1]; - [QGVAR(loadoutShared), [_contentPanelCtrl, [_profileName ,_loadoutName , _loadoutData]]] call CBA_fnc_remoteEvent; + + [QGVAR(loadoutShared), [_contentPanelCtrl, [_profileName, _loadoutName, _loadoutData]]] call CBA_fnc_remoteEvent; }; // Update share button text -_control ctrlSetText ( [ - localize LSTRING(buttonSharePrivateText), - localize LSTRING(buttonSharePublicText) +_control ctrlSetText ([ + LLSTRING(buttonSharePrivateText), + LLSTRING(buttonSharePublicText) ] select ((_contentPanelCtrl lnbValue [_contentPanelCursSel, 0]) == 1)); diff --git a/addons/arsenal/functions/fnc_buttonStats.sqf b/addons/arsenal/functions/fnc_buttonStats.sqf index 0eaac78a415..08ad8e287c5 100644 --- a/addons/arsenal/functions/fnc_buttonStats.sqf +++ b/addons/arsenal/functions/fnc_buttonStats.sqf @@ -17,15 +17,15 @@ params ["_display"]; (_display displayCtrl IDC_statsButton) ctrlShow GVAR(showStats); + GVAR(showStats) = !GVAR(showStats); { (_display displayCtrl _x) ctrlShow GVAR(showStats); -} foreach [ +} 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 index 48c9b4715e3..17bc0dfab04 100644 --- a/addons/arsenal/functions/fnc_buttonStatsPage.sqf +++ b/addons/arsenal/functions/fnc_buttonStatsPage.sqf @@ -21,7 +21,7 @@ if !(ctrlEnabled _control) exitWith {}; GVAR(statsInfo) params ["_isLeftPanel", "_statsIndex", "_panelControl", "_curSel", "_itemCfg"]; -private _pageList = [GVAR(statsPagesRight), GVAR(statsPagesLeft)] select (_isLeftPanel); +private _pageList = [GVAR(statsPagesRight), GVAR(statsPagesLeft)] select _isLeftPanel; private _newPageNumber = [(_pageList select _statsIndex) - 1, (_pageList select _statsIndex) + 1] select _nextPage; _pageList set [_statsIndex, _newPageNumber]; diff --git a/addons/arsenal/functions/fnc_clearSearchbar.sqf b/addons/arsenal/functions/fnc_clearSearchbar.sqf index a6b7b534dcb..ac43f92a470 100644 --- a/addons/arsenal/functions/fnc_clearSearchbar.sqf +++ b/addons/arsenal/functions/fnc_clearSearchbar.sqf @@ -19,7 +19,7 @@ params ["_display", "_control", "_rightButton"]; if (_rightButton != 1) exitWith {}; -_control ctrlSetText ''; +_control ctrlSetText ""; if (ctrlIDC _control == IDC_leftSearchbar) then { [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_compileSorts.sqf b/addons/arsenal/functions/fnc_compileSorts.sqf index 71f9885c091..fd790fa8323 100644 --- a/addons/arsenal/functions/fnc_compileSorts.sqf +++ b/addons/arsenal/functions/fnc_compileSorts.sqf @@ -16,6 +16,7 @@ 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 ""]; @@ -84,7 +85,7 @@ private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (confi if (_rightTabsList isNotEqualTo []) then { [_sortListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; }; -} foreach _configEntries; +} forEach _configEntries; missionNamespace setVariable [QGVAR(sortListLeftPanel), _sortListLeftPanel]; missionNamespace setVariable [QGVAR(sortListRightPanel), _sortListRightPanel]; diff --git a/addons/arsenal/functions/fnc_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf index 40c9d7cfa53..0639ef99134 100644 --- a/addons/arsenal/functions/fnc_compileStats.sqf +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -16,6 +16,7 @@ if (!isNil QGVAR(statsListLeftPanel)) exitWith {}; private _fnc_addToTabs = { params ["_tabsList", "_tabsToAddTo", "_sideString"]; + { private _currentTab = _tabsList select _x; private _availablePagesCount = {count _x < 5} count _currentTab; @@ -29,11 +30,11 @@ private _fnc_addToTabs = { if (count _x < 5) exitWith { (_currentTab select _forEachIndex) append [_arrayToSave]; }; - } foreach _currentTab; + } forEach _currentTab; } else { _currentTab pushBack [_arrayToSave]; }; - } foreach _tabsToAddTo; + } forEach _tabsToAddTo; }; private _fnc_sortLists = { @@ -44,15 +45,15 @@ private _fnc_sortLists = { { { reverse _x; - } foreach _x; + } forEach _x; _x sort false; { reverse _x; - } foreach _x; - } foreach _page; - } foreach _tabsList; + } forEach _x; + } forEach _page; + } forEach _tabsList; }; private _statsListLeftPanel = [ @@ -70,7 +71,7 @@ private _statsListLeftPanel = [ [[]], // GPS 11 [[]], // Radio 12 [[]], // Compass 13 - [[]] // Watch 14 + [[]] // Watch 14 ]; private _statsListRightPanel = [ @@ -106,13 +107,11 @@ private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (confi _finalArray = ["", _stats, _displayName, [_showBar, _showText], [{}, {}, _condition], _priority]; if (_showBar) then { - private _barStatement = compile (getText (_x >> "barStatement")); - (_finalArray select 4) set [0, _barStatement]; + (_finalArray select 4) set [0, compile (getText (_x >> "barStatement"))]; }; if (_showText) then { - private _textStatement = compile (getText (_x >> "textStatement")); - (_finalArray select 4) set [1, _textStatement]; + (_finalArray select 4) set [1, compile (getText (_x >> "textStatement"))]; }; TRACE_3("stats array", _finalArray, _leftTabsList, _rightTabsList); @@ -124,7 +123,7 @@ private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (confi if (count _rightTabsList > 0) then { [_statsListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; }; -} foreach _configEntries; +} forEach _configEntries; [_statsListLeftPanel] call _fnc_sortLists; [_statsListRightPanel] call _fnc_sortLists; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index b1212843a5c..5aebc52eb29 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Fill left panel. + * Author: Alganthe, johnb43 + * Fills left panel. * * Arguments: * 0: Arsenal display @@ -16,19 +16,21 @@ params ["_display", "_control"]; -private _ctrlIDC = ctrlIDC _control; - +// Fade old control background if (!isNil QGVAR(currentLeftPanel)) then { private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1); _previousCtrlBackground ctrlSetFade 1; _previousCtrlBackground ctrlCommit FADE_DELAY; }; +// Show new control background +private _ctrlIDC = ctrlIDC _control; private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); -private _ctrlPanel = _display displayCtrl IDC_leftTabContent; _ctrlBackground ctrlSetFade 0; _ctrlBackground ctrlCommit FADE_DELAY; +private _ctrlPanel = _display displayCtrl IDC_leftTabContent; + // Force a "refresh" animation of the panel _ctrlPanel ctrlSetFade 1; _ctrlPanel ctrlCommit 0; @@ -38,168 +40,226 @@ _ctrlPanel ctrlCommit FADE_DELAY; _ctrlPanel lbSetCurSel -1; // Handle icons and filling -switch true do { - case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]) : { +private _selectedItem = switch (true) do { + // Primary weapons, secondary weapons, handgun weapons + case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]): { // Purge old data lbClear _ctrlPanel; - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; + + // Add "Empty" entry + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; + + // Add selected tab's weapons + private _index = [IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find _ctrlIDC; { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach ((GVAR(virtualItems) select IDX_VIRT_WEAPONS) select ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find _ctrlIDC)); - }; - - case (_ctrlIDC in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) : { + } forEach ((GVAR(virtualItems) select IDX_VIRT_WEAPONS) select _index); + GVAR(currentItems) select _index + }; + // Uniforms, vests, backpacks + case (_ctrlIDC in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]): { + // Purge old data lbClear _ctrlPanel; - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; - // Filling + // Add "Empty" entry + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; + switch (_ctrlIDC) do { - case IDC_buttonUniform : { + // Add uniforms + case IDC_buttonUniform: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select IDX_VIRT_UNIFORM); - }; + } forEach (GVAR(virtualItems) select IDX_VIRT_UNIFORM); - case IDC_buttonVest : { + GVAR(currentItems) select IDX_CURR_UNIFORM + }; + // Add vests + case IDC_buttonVest: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select IDX_VIRT_VEST); - }; + } forEach (GVAR(virtualItems) select IDX_VIRT_VEST); - case IDC_buttonBackpack : { + GVAR(currentItems) select IDX_CURR_VEST + }; + // Add backpacks + case IDC_buttonBackpack: { { ["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select IDX_VIRT_BACKPACK); + } forEach (GVAR(virtualItems) select IDX_VIRT_BACKPACK); + + GVAR(currentItems) select IDX_CURR_BACKPACK }; }; }; - + // Other default { - GVAR(currentRightPanel) = nil; + // Don't reset right panel selection if left tab is binos + if (_ctrlIDC != IDC_buttonBinoculars) then { + GVAR(currentRightPanel) = nil; + }; lbClear _ctrlPanel; + // For every left tab except faces and voices, add "Empty" entry if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then { - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; }; switch (_ctrlIDC) do { + // Headgear case IDC_buttonHeadgear: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select IDX_VIRT_HEADGEAR); + } forEach (GVAR(virtualItems) select IDX_VIRT_HEADGEAR); + + GVAR(currentItems) select IDX_CURR_HEADGEAR }; - case IDC_buttonGoggles : { + // Facewear + case IDC_buttonGoggles: { { ["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select IDX_VIRT_GOGGLES); + } forEach (GVAR(virtualItems) select IDX_VIRT_GOGGLES); + + GVAR(currentItems) select IDX_CURR_GOGGLES }; - case IDC_buttonNVG : { + // NVGs + case IDC_buttonNVG: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 8); + } forEach (GVAR(virtualItems) select IDX_VIRT_NVG); + + GVAR(currentItems) select IDX_CURR_NVG }; - case IDC_buttonBinoculars : { + // Binoculars + case IDC_buttonBinoculars: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 9); + } forEach (GVAR(virtualItems) select IDX_VIRT_BINO); + + GVAR(currentItems) select IDX_CURR_BINO }; - case IDC_buttonMap : { + // Maps + case IDC_buttonMap: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 10); + } forEach (GVAR(virtualItems) select IDX_VIRT_MAP); + + GVAR(currentItems) select IDX_CURR_MAP }; - case IDC_buttonCompass : { + // Compasses + case IDC_buttonCompass: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 11); + } forEach (GVAR(virtualItems) select IDX_VIRT_COMPASS); + + GVAR(currentItems) select IDX_CURR_COMPASS }; - case IDC_buttonRadio : { + // Radios + case IDC_buttonRadio: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 12); + } forEach (GVAR(virtualItems) select IDX_VIRT_RADIO); + + GVAR(currentItems) select IDX_CURR_RADIO }; - case IDC_buttonWatch : { + // Watches + case IDC_buttonWatch: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 13); + } forEach (GVAR(virtualItems) select IDX_VIRT_WATCH); + + GVAR(currentItems) select IDX_CURR_WATCH }; - case IDC_buttonGPS : { + // GPS and UAV Terminals + case IDC_buttonGPS: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (GVAR(virtualItems) select 14); + } forEach (GVAR(virtualItems) select IDX_VIRT_COMMS); + + GVAR(currentItems) select IDX_CURR_COMMS }; - case IDC_buttonFace : { - { - { - if ( - getnumber (_x >> "disabled") == 0 && - {getText (_x >> "head") != ""} && - {configName _x != "Default"} - ) then { - private _configName = configName _x; - private _displayName = getText (_x >> "displayName"); - private _lbAdd = _ctrlPanel lbAdd _displayName; - _ctrlPanel lbSetData [_lbAdd, _configName]; - _ctrlPanel lbSetTooltip [_lbAdd,format ["%1\n%2",_displayName, _configName]]; - _x call ADDMODICON; - }; - } foreach ("true" configClasses _x); - } foreach ("true" configClasses (configfile >> "cfgfaces")); + // Faces + case IDC_buttonFace: { + private _lbAdd = -1; + + { + _y params ["_displayName", "_modPicture"]; + + _lbAdd = _ctrlPanel lbAdd _displayName; + _ctrlPanel lbSetData [_lbAdd, _x]; + _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]]; + _ctrlPanel lbSetPictureRight [_lbAdd, _modPicture]; + } forEach (uiNamespace getVariable [QGVAR(faceCache), createHashMap]); + + GVAR(currentFace) }; - case IDC_buttonVoice : { - private _voices = (configProperties [(configFile >> "CfgVoice"), "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [(configfile >> "CfgVoice" >> "NoVoice")]; + // Voices + case IDC_buttonVoice: { { ["CfgVoice", configName _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); - } foreach _voices; + } forEach (uiNamespace getVariable [QGVAR(voiceCache), []]); + + GVAR(currentVoice) }; - case IDC_buttonInsignia : { + // Insignia + case IDC_buttonInsignia: { + // Insignia from config { ["CfgUnitInsignia", configName _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); - } foreach ("true" configClasses (configFile >> "CfgUnitInsignia")); + } forEach (uiNamespace getVariable [QGVAR(insigniaCache), []]); + + private _displayName = ""; + private _className = ""; + private _lbAdd = -1; + // Insignia from mission file { - private _displayName = getText (_x >> "displayName"); - private _className = configName _x; - private _lbAdd = _ctrlPanel lbAdd _displayName; + _className = configName _x; + _displayName = getText (_x >> "displayName"); + _lbAdd = _ctrlPanel lbAdd _displayName; _ctrlPanel lbSetData [_lbAdd, _className]; _ctrlPanel lbSetPicture [_lbAdd, getText (_x >> "texture")]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; - } foreach ("true" configClasses (missionConfigFile >> "CfgUnitInsignia")); + } forEach ("true" configClasses (missionConfigFile >> "CfgUnitInsignia")); + + GVAR(currentInsignia) }; + // Unknown + default {""}; }; }; }; -// Done +// When switching tabs, clear searchbox if (GVAR(currentLeftPanel) != _ctrlIDC) then { (_display displayCtrl IDC_leftSearchbar) ctrlSetText ""; (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; }; +// Trigger event GVAR(currentLeftPanel) = _ctrlIDC; [QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent; // Sort -private _sortLeftCtrl = _display displayCtrl IDC_sortLeftTab; -[_display, _control, _sortLeftCtrl] call FUNC(fillSort); - -//Select current item -private _itemsToCheck = ((GVAR(currentItems) select [0,15]) + [GVAR(currentFace), GVAR(currentVoice), GVAR(currentInsignia)]) apply {tolower _x}; +[_display, _control, _display displayCtrl IDC_sortLeftTab] call FUNC(fillSort); -for "_lbIndex" from 0 to (lbSize _ctrlPanel - 1) do { - private _currentData = _ctrlPanel lbData _lbIndex; +// Try to select previously selected item again, otherwise select first item ("Empty") +if (_selectedItem != "") then { + private _index = 0; - if ((_currentData isNotEqualTo "") && {tolower _currentData in _itemsToCheck}) exitWith { - _ctrlPanel lbSetCurSel _lbIndex; + for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { + if ((_ctrlPanel lbData _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; }; -}; -if (lbCurSel _ctrlPanel < 0) then { + + _ctrlPanel lbSetCurSel _index; +} else { _ctrlPanel lbSetCurSel 0; }; diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf index ba47cc54fcf..92cca834c4c 100644 --- a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Fill loadouts list. * * Arguments: @@ -16,11 +16,9 @@ params ["_display", "_control"]; +(_display displayCtrl IDC_textEditBox) ctrlSetText ""; + private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; -private _textEditBoxCtrl= _display displayCtrl IDC_textEditBox; -_textEditBoxCtrl ctrlSetText ""; -private _sharingEnabled = (GVAR(allowSharedLoadouts) && {isMultiplayer}); -private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); // Force a "refresh" animation of the panel _contentPanelCtrl ctrlSetFade 1; @@ -31,98 +29,108 @@ _contentPanelCtrl ctrlCommit FADE_DELAY; _contentPanelCtrl lnbSetCurSelRow -1; lnbClear _contentPanelCtrl; -private _data = +(profileNamespace getvariable [QGVAR(saved_loadouts),[]]); +private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { + private _loadoutNameAndTab = ""; + private _loadoutCachedInfo = ""; + private _newRow = -1; + private _cfgWeapons = configFile >> "CfgWeapons"; + private _sharingEnabled = GVAR(allowSharedLoadouts) && {isMultiplayer}; + // Add all loadouts to loadout list { _x params ["_loadoutName", "_loadoutData"]; - private _loadoutCachedInfo = _contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab)); + _loadoutNameAndTab = _loadoutName + str GVAR(currentLoadoutsTab); + _loadoutCachedInfo = _contentPanelCtrl getVariable _loadoutNameAndTab; + // If not in cache, get info and cache it if (isNil "_loadoutCachedInfo") then { - [_loadoutData] call FUNC(verifyLoadout) - } else { - _loadoutCachedInfo - } params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; + _loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout); + _contentPanelCtrl setVariable [_loadoutNameAndTab, _loadoutCachedInfo]; - // Log missing / nil items to RPT - if (GVAR(EnableRPTLog) && {isNil "_loadoutCachedInfo"} && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then { + _loadoutCachedInfo params ["", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; - private _printComponent = "ACE_Arsenal - Loadout:"; - private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " "; - private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " "; + // Log missing / nil items to RPT (only once per arsenal session) + if (GVAR(EnableRPTLog) && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then { + private _printComponent = "ACE_Arsenal - Loadout:"; + private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " "; + private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " "; - diag_log text (format ["%1%5 %2%5 %3%5 %4", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, endl]); + diag_log text (format ["%1%5 %2%5 %3%5 %4", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, endl]); + }; }; + // Set position of loadouts different if in default loadout tab or if sharing is disabled if (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts || {!_sharingEnabled}) then { _contentPanelCtrl lnbSetColumnsPos [0, 0, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; } else { _contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; }; - private _newRow = _contentPanelCtrl lnbAddRow ["",_loadoutName]; - + _loadoutCachedInfo params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"]; _extendedLoadout params ["_loadout"]; + + _newRow = _contentPanelCtrl lnbAddRow ["", _loadoutName]; + ADD_LOADOUTS_LIST_PICTURES + // Change color on loadout lines that have items that aren't available or don't exist if (_nullItemsAmount > 0) then { - - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red } else { - if (_unavailableItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray }; }; - _contentPanelCtrl setVariable [_loadoutName + str GVAR(currentLoadoutsTab), [_extendedLoadout, _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]]; - - if ((profileName + _loadoutName) in _sharedLoadoutsVars && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts}) then { + // If it's a shared loadout and player is in the private loadouts tab, add icon + if (((profileName + _loadoutName) in _sharedLoadoutsVars) && {GVAR(currentLoadoutsTab) == IDC_buttonMyLoadouts}) then { _contentPanelCtrl lnbSetPicture [[_newRow, 0], QPATHTOF(data\iconPublic.paa)]; _contentPanelCtrl lnbSetValue [[_newRow, 0], 1]; }; - } foreach ([_data, +GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); + } forEach ([profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); } else { + private _allPlayerNames = allPlayers apply {name _x}; + private _newRow = -1; + private _cfgWeapons = configFile >> "CfgWeapons"; { _x params ["_playerName", "_loadoutName", "_loadoutData"]; - if ((allPlayers apply {name _x}) find _playerName == -1) then { - + // If player who shared loadout doesn't exist anymore, unshare loadout + if !(_playerName in _allPlayerNames) then { private _loadoutVar = _playerName + _loadoutName; GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; - _sharedLoadoutsVars = _sharedLoadoutsVars - [_loadoutVar]; - GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars, true]; + GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars - [_loadoutVar], true]; [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; } else { - ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + _extendedLoadout params ["_loadout"]; _contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; - private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; + _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; - _extendedLoadout params ["_loadout"]; ADD_LOADOUTS_LIST_PICTURES - _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; + _contentPanelCtrl lnbSetData [[_newRow, 1], _loadoutVar]; + // Change color on loadout lines that have items that aren't available or don't exist if (_nullItemsAmount > 0) then { - - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red } else { - if (_unavailableItemsAmount > 0) then { - _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; + _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray }; }; }; - } foreach (_sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}); + } forEach (_sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}); }; [QGVAR(loadoutsListFilled), [_display, _control]] call CBA_fnc_localEvent; +// Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index 281662ec0ca..e4cd1a96b44 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Fill right panel. + * Author: Alganthe, johnb43 + * Fills right panel. * * Arguments: * 0: Arsenal display @@ -16,8 +16,6 @@ params ["_display", "_control"]; -private _ctrlIDC = ctrlIDC _control; - // Fade old control background if (!isNil QGVAR(currentRightPanel)) then { private _previousCtrlBackground = _display displayCtrl (GVAR(currentRightPanel) - 1); @@ -26,6 +24,7 @@ if (!isNil QGVAR(currentRightPanel)) then { }; // Show new control background +private _ctrlIDC = ctrlIDC _control; private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); _ctrlBackground ctrlShow true; _ctrlBackground ctrlSetFade 0; @@ -33,6 +32,7 @@ _ctrlBackground ctrlCommit FADE_DELAY; private _searchbarCtrl = _display displayCtrl IDC_rightSearchbar; +// Show right search bar if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { _searchbarCtrl ctrlShow true; _searchbarCtrl ctrlSetFade 0; @@ -42,101 +42,111 @@ if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { private _fnc_fill_right_Container = { params ["_configCategory", "_className", "_isMagazine", ["_isUnique", false, [false]]]; - private _cacheNamespace = _ctrlPanel; - private _cachedItemInfo = _cacheNamespace getVariable [_configCategory+_className, []]; - - if (!(_className in GVAR(virtualItemsFlat))) then { + // If items is not in the arsenal, it must be unique + if !(_className in GVAR(virtualItemsFlat)) then { _isUnique = true; }; - // Not in cache. So get info and put into cache + private _cachedItemInfo = GVAR(rightPanelCache) getOrDefault [_configCategory + _className, []]; + + // If not in cache, find info and cache it for later use if (_cachedItemInfo isEqualTo []) then { + // Get display name, picture and mass private _configPath = configFile >> _configCategory >> _className; _cachedItemInfo set [0, getText (_configPath >> "displayName")]; _cachedItemInfo set [1, getText (_configPath >> "picture")]; - _cachedItemInfo set [2, [getNumber (_configPath >> "itemInfo" >> "mass"), getNumber (_configPath >> "mass")] select _isMagazine]; + _cachedItemInfo set [2, if (_isMagazine) then {getNumber (_configPath >> "mass")} else {getNumber (_configPath >> "itemInfo" >> "mass")}]; - _cacheNamespace setVariable [_configCategory+_className, _cachedItemInfo]; + GVAR(rightPanelCache) set [_configCategory + _className, _cachedItemInfo] }; - _cachedItemInfo params ["_displayName","_picture", "_mass"]; + _cachedItemInfo params ["_displayName", "_picture", "_mass"]; private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; - private _columns = count lnbGetColumnsPosition _ctrlPanel; - _ctrlPanel lnbSetData [[_lbAdd, 0], _x]; + _ctrlPanel lnbSetData [[_lbAdd, 0], _className]; _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; - _ctrlPanel setVariable [_x, _mass]; - _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select (_isUnique)]; - _ctrlPanel lbSetTooltip [_lbAdd * _columns,format ["%1\n%2", _displayName, _x]]; + _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select _isUnique]; + _ctrlPanel lbSetTooltip [_lbAdd * (count lnbGetColumnsPosition _ctrlPanel), format ["%1\n%2", _displayName, _className]]; + _ctrlPanel setVariable [_className, _mass]; }; -// Retrieve compatible mags -private _compatibleItems = []; -private _compatibleMagazines = [[[], []], [[], []], [[], []]]; -{ - if (_x != "") then { - private _weaponConfig = (configFile >> "CfgWeapons" >> _x); - private _index = _forEachIndex; - - { - private _subIndex = _forEachIndex min 1; - { - ((_compatibleMagazines select _index) select _subIndex) pushBackUnique (configName (configFile >> "CfgMagazines" >> _x)) - } foreach ([getArray (_weaponConfig >> _x >> "magazines"), getArray (_weaponConfig >> "magazines")] select (_x == "this")); +// Get all weapons on unit +private _weapons = [primaryWeapon GVAR(center), handgunWeapon GVAR(center), secondaryWeapon GVAR(center), binocular GVAR(center)]; +private _compatibleMagazines = []; +private _muzzles = []; - // Magazine groups - { - private _magazineGroups = uiNamespace getVariable [QGVAR(magazineGroups), createHashMap]; - private _magArray = _magazineGroups get (toLower _x); - {((_compatibleMagazines select _index) select _subIndex) pushBackUnique _x} forEach _magArray; - } foreach ([getArray (_weaponConfig >> _x >> "magazineWell"), getArray (_weaponConfig >> "magazineWell")] select (_x == "this")); +// Get all compatibles magazines with unit's weapons +{ + _muzzles = _x call CBA_fnc_getMuzzles; - } foreach getArray (_weaponConfig >> "muzzles"); - }; -} foreach [primaryWeapon GVAR(center), handgunWeapon GVAR(center), secondaryWeapon GVAR(center)]; - -private _itemsToCheck = []; -private _compatibleMagsPrimaryMuzzle = []; -private _compatibleMagsSecondaryMuzzle = []; + // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) + // Assumption: One weapon can have two muzzles maximum + _compatibleMagazines pushBack [compatibleMagazines [_x, _muzzles param [0, ""]], compatibleMagazines [_x, _muzzles param [1, ""]]]; +} forEach _weapons; +// This is used for the "compatible magazines" tab when a container is open private _allCompatibleMags = []; + { _allCompatibleMags append (_x select 0); _allCompatibleMags append (_x select 1); -} foreach _compatibleMagazines; +} forEach _compatibleMagazines; private _ctrlPanel = _display displayCtrl IDC_rightTabContent; +private _listnBox = _display displayCtrl IDC_rightTabContentListnBox; + +// Reset right panel content +lbClear _ctrlPanel; +lbClear _listnBox; + +_ctrlPanel lbSetCurSel -1; +_listnBox lbSetCurSel -1; + +// Retrieve compatible items +private _compatibleItems = []; +private _itemsToCheck = []; +private _compatibleMagsPrimaryMuzzle = []; +private _compatibleMagsSecondaryMuzzle = []; switch (GVAR(currentLeftPanel)) do { - case IDC_buttonPrimaryWeapon : { + // If weapons or binoculars are chosen, get their compatible magazines & items + // Primary weapon + case IDC_buttonPrimaryWeapon: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 0 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 0 select 1; - _compatibleItems = (primaryWeapon GVAR(center)) call bis_fnc_compatibleItems; - _itemsToCheck = GVAR(currentItems) select 18; + _compatibleItems = compatibleItems (_weapons select 0)/* call CBA_fnc_compatibleItems*/; + _itemsToCheck = GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS; }; - - case IDC_buttonHandgun : { + // Handgun weapon + case IDC_buttonHandgun: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 1 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 1 select 1; - _compatibleItems = (handgunWeapon GVAR(center)) call bis_fnc_compatibleItems; - _itemsToCheck = GVAR(currentItems) select 20; + _compatibleItems = (_weapons select 1) call CBA_fnc_compatibleItems; + _itemsToCheck = GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS; }; - - case IDC_buttonSecondaryWeapon : { + // Secondary weapon + case IDC_buttonSecondaryWeapon: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 2 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 2 select 1; - _compatibleItems = (secondaryWeapon GVAR(center)) call bis_fnc_compatibleItems; - _itemsToCheck = GVAR(currentItems) select 19; + _compatibleItems = (_weapons select 2) call CBA_fnc_compatibleItems; + _itemsToCheck = GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS; }; - + // Binoculars + case IDC_buttonBinoculars: { + _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 3 select 0; + _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 3 select 1; + _compatibleItems = (_weapons select 3) call CBA_fnc_compatibleItems; + _itemsToCheck = GVAR(currentItems) select IDX_CURR_BINO_ITEMS; + }; + // Uniform, vest or backpack case IDC_buttonUniform; case IDC_buttonVest; - case IDC_buttonBackpack : { - _ctrlPanel = _display displayCtrl IDC_rightTabContentListnBox; + case IDC_buttonBackpack: { + _ctrlPanel = _listnBox; }; }; @@ -146,238 +156,260 @@ _ctrlPanel ctrlCommit 0; _ctrlPanel ctrlSetFade 0; _ctrlPanel ctrlCommit FADE_DELAY; -_itemsToCheck = _itemsToCheck apply {toLower _x}; -_compatibleItems = _compatibleItems apply {toLower _x}; +// Check if the left panel is a weapon. If so, right panel will be compatible items with weapon only +private _leftPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon, IDC_buttonBinoculars]; -lbClear (_display displayCtrl IDC_rightTabContentListnBox); -lbClear (_display displayCtrl IDC_rightTabContent); - -(_display displayCtrl IDC_rightTabContentListnBox) lbSetCurSel -1; -(_display displayCtrl IDC_rightTabContent) lbSetCurSel -1; - -private _leftPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]; - -if (_ctrlIDC in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] && {_leftPanelState}) then { - private _addEmpty = _ctrlPanel lbadd format [" <%1>",localize "str_empty"]; - _ctrlPanel lbsetvalue [_addEmpty, -1]; +// Add an empty entry if left panel is a weapon or bino +if (_leftPanelState && {_ctrlIDC in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}) then { + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; }; +// Fill right panel according to category choice switch (_ctrlIDC) do { - - case IDC_buttonOptic : { + // Optics + case IDC_buttonOptic: { if (_leftPanelState) then { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 0) apply {toLower _x})); + } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS)) arrayIntersect _compatibleItems); } else { { ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 0); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS); + { ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 0); + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS); }; }; - - case IDC_buttonItemAcc : { + // Flashlights + case IDC_buttonItemAcc: { if (_leftPanelState) then { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 1) apply {toLower _x})); + } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)) arrayIntersect _compatibleItems); } else { { ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 1); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS); + { ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 1); + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS); }; }; - - case IDC_buttonMuzzle : { + // Muzzle attachments + case IDC_buttonMuzzle: { if (_leftPanelState) then { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 2) apply {toLower _x})); + } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS)) arrayIntersect _compatibleItems); } else { { ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 2); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS); + { ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 2); + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS); }; }; - - case IDC_buttonBipod : { + // Bipods + case IDC_buttonBipod: { if (_leftPanelState) then { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach (_compatibleItems arrayIntersect (((GVAR(virtualItems) select 1) select 3) apply {toLower _x})); + } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS)) arrayIntersect _compatibleItems); } else { { ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 1) select 3); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS); + { ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 22) select 3); + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS); }; }; - - case IDC_buttonCurrentMag : { + // Current primary muzzle compatible magazines + case IDC_buttonCurrentMag: { if (_leftPanelState) then { { ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsPrimaryMuzzle); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsPrimaryMuzzle); }; }; - - case IDC_buttonCurrentMag2 : { + // Current secondary muzzle compatible magazines + case IDC_buttonCurrentMag2: { if (_leftPanelState) then { { ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } foreach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsSecondaryMuzzle); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsSecondaryMuzzle); }; }; - - case IDC_buttonMag : { + // All compatible magazines + case IDC_buttonMag: { { ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); + { ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 19) arrayIntersect _allCompatibleMags); + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); }; - - case IDC_buttonMagALL : { + // All magazines + case IDC_buttonMagALL: { { ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + } forEach (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 19); + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL); }; - - case IDC_buttonThrow : { + // Grenades + case IDC_buttonThrow: { { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 15); + ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + } forEach (GVAR(virtualItems) select IDX_VIRT_GRENADES); + { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 20); + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GRENADES); }; - - case IDC_buttonPut : { + // Explosives + case IDC_buttonPut: { { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 16); + ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + } forEach (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES); + { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; - } foreach (GVAR(virtualItems) select 21); + ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_EXPLOSIVES); }; + // Misc. items + case IDC_buttonMisc: { + // Don't add items that will be in a custom right panel button + private _items = []; - case IDC_buttonMisc : { - // hide custom button items - private _blockItems = []; if (!isNil QGVAR(customRightPanelButtons)) then { { if (!isNil "_x") then { - _blockItems append (_x select 0); + _items append (_x select 0); }; } forEach GVAR(customRightPanelButtons); }; + // "Regular" misc. items { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select 17) select {!((toLower _x) in _blockItems)}); - + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS) select {!(_x in _items)}); + // Unique items { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 18) select {!((toLower _x) in _blockItems)}); + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) select {!(_x in _items)}); + // Unique backpacks { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 23) select {!((toLower _x) in _blockItems)}); + ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) select {!(_x in _items)}); + // Unique goggles { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 24) select {!((toLower _x) in _blockItems)}); + ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) select {!(_x in _items)}); }; - + // Custom buttons default { - private _index = [RIGHT_PANEL_CUSTOM_BUTTONS] find _ctrlIDC; - if (_index != -1) then { - private _data = GVAR(customRightPanelButtons) param [_index]; - - if (!isNil "_data") then { - private _items = _data select 0; - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 17) select {(toLower _x) in _items}); - - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 18) select {(toLower _x) in _items}); - { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 23) select {(toLower _x) in _items}); - { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; - } foreach ((GVAR(virtualItems) select 24) select {(toLower _x) in _items}); - }; + private _items = (GVAR(customRightPanelButtons) param [[RIGHT_PANEL_CUSTOM_BUTTONS] find _ctrlIDC, []]) param [0, []]; + + if (_items isNotEqualTo []) then { + // "Regular" misc. items + { + ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS) select {_x in _items}); + // Unique items + { + ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) select {_x in _items}); + // Unique backpacks + { + ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) select {_x in _items}); + // Unique goggles + { + ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) select {_x in _items}); }; }; }; +// Reset right panel search bar (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; GVAR(currentRightPanel) = _ctrlIDC; - [QGVAR(rightPanelFilled), [_display, GVAR(currentLeftPanel), _ctrlIDC]] call CBA_fnc_localEvent; -// Add current items and change progress bar +// Add current items, change progress bar of container load and get relevant container if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { - - private _maxLoad = 0; + private _containerItems = []; private _container = switch (GVAR(currentLeftPanel)) do { - case IDC_buttonUniform : { + // Uniform + case IDC_buttonUniform: { + // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); - _maxLoad = gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass"); - uniformItems GVAR(center) + + _containerItems = uniformItems GVAR(center); + + uniformContainer GVAR(center) }; - case IDC_buttonVest : { + // Vest + case IDC_buttonVest: { + // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); - _maxLoad = gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass"); - vestItems GVAR(center) + + _containerItems = vestItems GVAR(center); + + vestContainer GVAR(center) }; - case IDC_buttonBackpack : { + // Backpack + case IDC_buttonBackpack: { + // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); - _maxLoad = backpack GVAR(center); - backpackItems GVAR(center) + + _containerItems = backpackItems GVAR(center); + + backpackContainer GVAR(center) }; }; - for "_l" from 0 to ((lnbsize _ctrlPanel select 0) - 1) do { - private _class = _ctrlPanel lnbData [_l, 0]; - _ctrlPanel lnbSetText [[_l, 2], ["0", str ({_x == _class} count _container)] select (_class in _container)]; + // Find out how many items of a type there are and update the number displayed + private _class = ""; + + for "_lbIndex" from 0 to (lnbSize _ctrlPanel select 0) - 1 do { + _class = _ctrlPanel lnbData [_lbIndex, 0]; + _ctrlPanel lnbSetText [[_lbIndex, 2], str ({_x == _class} count _containerItems)]; }; - [_ctrlPanel, _maxLoad] call FUNC(updateRightPanel); + // Refresh availibility of items based on space remaining in container + [_ctrlPanel, _container, _containerItems isNotEqualTo []] call FUNC(updateRightPanel); }; // Sorting -private _sortRightCtrl = _display displayCtrl IDC_sortRightTab; -[_display, _control, _sortRightCtrl] call FUNC(fillSort); +[_display, _control, _display displayCtrl IDC_sortRightTab] call FUNC(fillSort); -// Select current data if not in a container +// Remove empty entries (for comparison below) +_itemsToCheck = _itemsToCheck - [""]; + +// Try to select previously selected item again, otherwise select first item ("Empty") if (_itemsToCheck isNotEqualTo []) then { - for "_lbIndex" from 0 to (lbSize _ctrlPanel - 1) do { - private _currentData = _ctrlPanel lbData _lbIndex; + private _index = 0; - if ((_currentData != "") && {tolower _currentData in _itemsToCheck}) exitWith { - _ctrlPanel lbSetCurSel _lbIndex; + for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { + if ((_ctrlPanel lbData _lbIndex) in _itemsToCheck) exitWith { + _index = _lbIndex; }; }; - if (lbCurSel _ctrlPanel < 0) then { - _ctrlPanel lbSetCurSel 0; - }; + _ctrlPanel lbSetCurSel _index; +} else { + _ctrlPanel lbSetCurSel 0; }; diff --git a/addons/arsenal/functions/fnc_fillSort.sqf b/addons/arsenal/functions/fnc_fillSort.sqf index 3516b5b6bec..213b124e3ec 100644 --- a/addons/arsenal/functions/fnc_fillSort.sqf +++ b/addons/arsenal/functions/fnc_fillSort.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" /* * Author: Alganthe, Brett Mayson - * Fill right panel. + * Fills the sort menu. * * Arguments: * 0: Arsenal display @@ -20,46 +20,50 @@ params ["_display", "_control", "_sortCtrl"]; lbClear _sortCtrl; private _right = false; -private _rightSort = ctrlIDC _sortCtrl == 17; +private _rightSort = ctrlIDC _sortCtrl == IDC_sortRightTab; -private _sorts = if (_rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform ,IDC_buttonVest, IDC_buttonBackpack]}) then { +private _sorts = if (_rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}) then { _right = true; + + // Right panel for uniforms, vest and backpacks 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_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_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 + + switch (true) do { + // Right panel for weapons + case (_rightSort): { GVAR(sortListRightPanel) select ( switch (_idc) do { - case IDC_buttonOptic: { 0 }; - case IDC_buttonItemAcc: { 1 }; - case IDC_buttonMuzzle: { 2 }; - case IDC_buttonBipod: { 3 }; + 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_buttonMagALL: {4}; + case IDC_buttonThrow: {5}; + case IDC_buttonPut: {6}; + case IDC_buttonMisc: {7}; } ) }; + // Left panel default { GVAR(sortListLeftPanel) select ([ IDC_buttonPrimaryWeapon, @@ -89,11 +93,17 @@ private _lastSort = [GVAR(lastSortLeft), GVAR(lastSortRight)] select _rightSort; private _sortIndex = 0; { - if (_x isEqualTo []) exitWith {}; + if (_x isEqualTo []) then { + continue; + }; + _x params ["_sortName", "_displayName", "", "_condition"]; + + // Check if sort if available for this panel if ([_right] call _condition) then { private _index = _sortCtrl lbAdd _displayName; _sortCtrl lbSetData [_index, _sortName]; + if (_displayName isEqualTo _lastSort) then { _sortIndex = _index; }; diff --git a/addons/arsenal/functions/fnc_getLoadout.sqf b/addons/arsenal/functions/fnc_getLoadout.sqf index 017ef296189..54767264eaa 100644 --- a/addons/arsenal/functions/fnc_getLoadout.sqf +++ b/addons/arsenal/functions/fnc_getLoadout.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Brett Mayson - * Get the extended loadout of a unit, including identity options if enabled + * Get the extended loadout of a unit, including identity options if enabled. * * Arguments: * 0: Unit @@ -21,14 +21,20 @@ if (isNull _unit) exitWith {}; ([_unit] call CBA_fnc_getLoadout) params ["_loadout", "_extendedInfo"]; +// Set face if enabled if (GVAR(loadoutsSaveFace)) then { _extendedInfo set [QGVAR(face), face _unit]; }; + +// Set voice if enabled if (GVAR(loadoutsSaveVoice)) then { _extendedInfo set [QGVAR(voice), speaker _unit]; }; + +// Set insignia if enabled if (GVAR(loadoutsSaveInsignia)) then { - private _insignia = _unit getVariable ["BIS_fnc_setUnitInsignia_class", ""]; + private _insignia = _unit call BIS_fnc_getUnitInsignia; + if (_insignia != "") then { _extendedInfo set [QGVAR(insignia), _insignia]; }; diff --git a/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf index 2911e7aa199..8e6090caf20 100644 --- a/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf +++ b/addons/arsenal/functions/fnc_handleLoadoutsSearchbar.sqf @@ -16,30 +16,56 @@ params ["_display", "_control"]; -private _textString = ctrlText _control; - private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; -if !(GVAR(lastSearchTextLoadouts) isEqualTo "" || {(_textString find GVAR(lastSearchTextLoadouts)) == 0}) then {//don't refill if there is no need +// Get the currently selected item in panel +private _selectedLoadoutIndex = lnbCurSelRow _contentPanelCtrl; +private _selectedLoadout = ""; + +// If something is selected, save it +if (_selectedLoadoutIndex != -1) then { + _selectedLoadout = _contentPanelCtrl lnbText [_selectedLoadoutIndex, 1]; +}; + +private _searchString = ctrlText _control; + +// Don't refill if there is no need +if (GVAR(lastSearchTextLoadouts) != "" && {(_searchString find GVAR(lastSearchTextLoadouts)) != 0}) then { [_display, _display displayCtrl GVAR(currentLoadoutsTab)] call FUNC(fillLoadoutsList); }; -GVAR(lastSearchTextLoadouts) = _textString; -if (count _textString == 0) exitWith {}; +GVAR(lastSearchTextLoadouts) = _searchString; -private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +// If nothing searched, quit here +if (_searchString != "") then { + _searchString = toLower _searchString; -private _itemsToGo = (lnbSize _contentPanelCtrl) select 0; -private _lbIndex = 0; -while {_itemsToGo > 0} do { - private _currentData = _contentPanelCtrl lnbText [_lbIndex, 1]; - private _currentClassname = _contentPanelCtrl lnbData [_lbIndex, 0]; + private _loadoutName = ""; + private _loadout = []; + private _currentTab = str GVAR(currentLoadoutsTab); - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { - _contentPanelCtrl lnbDeleteRow _lbIndex; - } else { - _lbIndex = _lbIndex + 1; + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lnbSize _contentPanelCtrl select 0) - 1 to 0 step -1 do { + _loadoutName = toLower (_contentPanelCtrl lnbText [_lbIndex, 1]); + + // Remove item in panel if it doesn't match search, skip otherwise + if ((_loadoutName == "") || {!(_searchString in _loadoutName)}) then { + _contentPanelCtrl lnbDeleteRow _lbIndex; + }; + }; +}; + +// Try to select previously selected item again, otherwise select nothing +if (_selectedLoadoutIndex != -1) then { + private _index = -1; + + for "_lbIndex" from 0 to (lnbSize _contentPanelCtrl select 0) - 1 do { + if ((_contentPanelCtrl lnbText [_lbIndex, 1]) == _selectedLoadout) exitWith { + _index = _lbIndex; + }; }; - _itemsToGo = _itemsToGo - 1; + + _contentPanelCtrl lnbSetCurSelRow _index; +} else { + _contentPanelCtrl lnbSetCurSelRow -1; }; -_contentPanelCtrl lnbSetCurSelRow -1; diff --git a/addons/arsenal/functions/fnc_handleMouse.sqf b/addons/arsenal/functions/fnc_handleMouse.sqf index 7d2fa2c9e2e..9f3f0dccc8b 100644 --- a/addons/arsenal/functions/fnc_handleMouse.sqf +++ b/addons/arsenal/functions/fnc_handleMouse.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Karel Moricky, modified by Alganthe + * Author: Karel Moricky, modified by Alganthe, johnb43 * Update the camera position and pitch/bank. * Modernized a bit, modified to fit the rewrite. * @@ -19,50 +19,53 @@ */ params ["", "_args"]; - _args params ["_control", "_mouseX", "_mouseY"]; -GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV", "_helperPos"]; + +GVAR(cameraPosition) params ["", "_dirH", "_dirV", "_helperPos"]; GVAR(mouseButtonState) params ["_LMB", "_RMB"]; if (count _LMB > 0) then { _LMB params ["_LMBcursorX", "_LMBcursorY"]; - private _dX = [(_mouseX - _LMBcursorX), (_LMBcursorX - _mouseX)] select GVAR(camInverted); - private _dY = [(_mouseY -_LMBcursorY), (_LMBcursorY - _mouseY)] select GVAR(camInverted); - GVAR(mouseButtonState) set [0,[_mouseX,_mouseY]]; + private _dX = [_mouseX - _LMBcursorX, _LMBcursorX - _mouseX] select GVAR(camInverted); + private _dY = [_mouseY -_LMBcursorY, _LMBcursorY - _mouseY] select GVAR(camInverted); - private _centerBox = boundingboxreal GVAR(center); + private _centerBox = boundingBoxReal GVAR(center); private _centerSizeBottom = _centerBox select 0 select 2; private _centerSizeUp = _centerBox select 1 select 2; - private _centerSize = sqrt ([_centerBox select 0 select 0,_centerBox select 0 select 1] distance [_centerBox select 1 select 0,_centerBox select 1 select 1]); + private _centerSize = sqrt ([_centerBox select 0 select 0, _centerBox select 0 select 1] distance [_centerBox select 1 select 0, _centerBox select 1 select 1]); + + _helperPos = [_helperPos, _dX * _centerSize, _dirH - 90] call BIS_fnc_relPos; - _helperPos = [_helperPos, _dX * _centerSize, _dirH - 90] call bis_fnc_relpos; _helperPos = [ - [0,0,((_helperPos select 2) - _dY * _centerSize) max _centerSizeBottom min _centerSizeUp], - ([0,0,0] distance2D _helperPos) min _centerSize, - [0,0,0] getDir _helperPos - ] call bis_fnc_relpos; + [0, 0, ((_helperPos select 2) - _dY * _centerSize) max _centerSizeBottom min _centerSizeUp], + ([0, 0, 0] distance2D _helperPos) min _centerSize, + [0, 0, 0] getDir _helperPos + ] call BIS_fnc_relPos; - _helperPos set [2,(_helperPos select 2) max ((boundingboxreal GVAR(center) select 0 select 2) + 0.2)]; + _helperPos set [2, (_helperPos select 2) max ((_centerBox select 0 select 2) + 0.2)]; - GVAR(cameraPosition) set [3,_helperPos]; + GVAR(cameraPosition) set [3, _helperPos]; + GVAR(mouseButtonState) set [0, [_mouseX, _mouseY]]; }; if (count _RMB > 0) then { _RMB params ["_RMBcursorX", "_RMBcursorY"]; + private _dX = (_RMBcursorX - _mouseX) * 0.75; private _dY = (_RMBcursorY - _mouseY) * 0.75; + _helperPos = [ - [0,0,_helperPos select 2], - [0,0,0] distance2D _helperPos, - ([0,0,0] getDir _helperPos) - _dX * 360 - ] call bis_fnc_relpos; + [0, 0, _helperPos select 2], + [0, 0, 0] distance2D _helperPos, + ([0, 0, 0] getDir _helperPos) - _dX * 360 + ] call BIS_fnc_relPos; - GVAR(cameraPosition) set [1,(_dirH - _dX * 360)]; - GVAR(cameraPosition) set [2,(_dirV - _dY * 100) max -89 min 89]; - GVAR(cameraPosition) set [3,_helperPos]; - GVAR(mouseButtonState) set [1,[_mouseX,_mouseY]]; + GVAR(cameraPosition) set [1, _dirH - _dX * 360]; + GVAR(cameraPosition) set [2, (_dirV - _dY * 100) max -89 min 89]; + GVAR(cameraPosition) set [3, _helperPos]; + GVAR(mouseButtonState) set [1, [_mouseX, _mouseY]]; }; -if (!alive (GVAR(center)) || isnull GVAR(center)) then { - (ctrlParent _control) closeDisplay 2; +if (!alive GVAR(center)) then { + (ctrlParent _control) closeDisplay IDC_CANCEL; }; diff --git a/addons/arsenal/functions/fnc_handleScrollWheel.sqf b/addons/arsenal/functions/fnc_handleScrollWheel.sqf index 0fec3e7c5b1..559fec04fc3 100644 --- a/addons/arsenal/functions/fnc_handleScrollWheel.sqf +++ b/addons/arsenal/functions/fnc_handleScrollWheel.sqf @@ -1,12 +1,13 @@ #include "script_component.hpp" -#include "..\defines.hpp" /* * Author: Alganthe * Handle the mouse wheel. * * Arguments: * 0: Not used - * 1: Mousewheel Z position + * 1: onMouseZChanged EH return + * 1.1: Not used + * 1.2: Mousewheel Z position * * Return Value: * None @@ -17,7 +18,8 @@ params ["", "_args"]; _args params ["", "_zPos"]; -private _distanceMax = ((boundingboxreal GVAR(center) select 0) vectordistance (boundingboxreal GVAR(center) select 1)) * 1.5; +private _boundingBoxReal = boundingBoxReal GVAR(center); +private _distanceMax = ((_boundingBoxReal select 0) vectorDistance (_boundingBoxReal select 1)) * 1.5; private _distanceMin = _distanceMax * 0.15; private _distance = GVAR(cameraPosition) select 0; diff --git a/addons/arsenal/functions/fnc_handleSearchbar.sqf b/addons/arsenal/functions/fnc_handleSearchbar.sqf index 5632006f436..006e77541d5 100644 --- a/addons/arsenal/functions/fnc_handleSearchbar.sqf +++ b/addons/arsenal/functions/fnc_handleSearchbar.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles keyboard inputs inside the searchbars text boxes. * * Arguments: @@ -16,77 +16,162 @@ params ["_display", "_control"]; -private _textString = ctrlText _control; +private _searchString = ctrlText _control; +// Right panel search bar if ((ctrlIDC _control) == IDC_rightSearchbar) then { - if !(GVAR(lastSearchTextRight) isEqualTo "" || {(_textString find GVAR(lastSearchTextRight)) == 0}) then {//don't refill if there is no need + // Don't refill if there is no need + if (GVAR(lastSearchTextRight) != "" && {(_searchString find GVAR(lastSearchTextRight)) != 0}) then { [_display, _display displayCtrl GVAR(currentRightPanel)] call FUNC(fillRightPanel); }; - GVAR(lastSearchTextRight) = _textString; - if (count _textString == 0) exitWith {}; - private _rightPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]; - private _rightPanelCtrl = [_display displayCtrl IDC_rightTabContentListnBox, _display displayCtrl IDC_rightTabContent] select (_rightPanelState); + GVAR(lastSearchTextRight) = _searchString; + // If nothing searched, quit here + if (_searchString == "") exitWith {}; + + private _rightPanelState = GVAR(currentLeftPanel) in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon, IDC_buttonBinoculars]; + private _rightPanelCtrl = [_display displayCtrl IDC_rightTabContentListnBox, _display displayCtrl IDC_rightTabContent] select _rightPanelState; + + _searchString = toLower _searchString; + + // If right panel selection is weapons or binoculars if (_rightPanelState) then { + // Get the currently selected item in panel + private _selectedItemIndex = lbCurSel _rightPanelCtrl; + private _selectedItem = ""; + + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _rightPanelCtrl lbText _selectedItemIndex; + }; - private _itemsToGo = lbSize _rightPanelCtrl; - private _lbIndex = 0; - while {_itemsToGo > 0} do { - private _currentData = _rightPanelCtrl lbText _lbIndex; - private _currentClassname = _rightPanelCtrl lbData _lbIndex; + private _currentDisplayName = ""; + private _currentClassname = ""; - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lbSize _rightPanelCtrl) - 1 to 0 step -1 do { + _currentDisplayName = toLower (_rightPanelCtrl lbText _lbIndex); + _currentClassname = toLower (_rightPanelCtrl lbData _lbIndex); + + // Remove item in panel if it doesn't match search, skip otherwise + if ((_currentDisplayName == "") || {!(_searchString in _currentDisplayName) && {!(_searchString in _currentClassname)}}) then { _rightPanelCtrl lbDelete _lbIndex; - } else { - _lbIndex = _lbIndex + 1; }; - _itemsToGo = _itemsToGo - 1; }; - _rightPanelCtrl lbSetCurSel -1; + + // Try to select previously selected item again, otherwise select nothing + if (_selectedItemIndex != -1) then { + private _index = -1; + + // Try to find previously selected item in panel + for "_lbIndex" from 0 to (lbSize _rightPanelCtrl) - 1 do { + if ((_rightPanelCtrl lbText _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + // Select old item if found, otherwise don't select anything + _rightPanelCtrl lbSetCurSel _index; + } else { + _rightPanelCtrl lbSetCurSel -1; + }; } else { + // Get the currently selected item in panel + private _selectedItemIndex = lnbCurSelRow _rightPanelCtrl; + private _selectedItem = ""; + + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _rightPanelCtrl lnbText [_selectedItemIndex, 1]; + }; + + private _currentDisplayName = ""; + private _currentClassname = ""; - private _itemsToGo = (lnbSize _rightPanelCtrl) select 0; - private _lbIndex = 0; - while {_itemsToGo > 0} do { - private _currentData = _rightPanelCtrl lnbText [_lbIndex, 1]; - private _currentClassname = _rightPanelCtrl lnbData [_lbIndex, 0]; + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lnbSize _rightPanelCtrl select 0) - 1 to 0 step -1 do { + _currentDisplayName = toLower (_rightPanelCtrl lnbText [_lbIndex, 1]); + _currentClassname = toLower (_rightPanelCtrl lnbData [_lbIndex, 0]); - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + // Remove item in panel if it doesn't match search, skip otherwise + if ((_currentDisplayName == "") || {!(_searchString in _currentDisplayName) && {!(_searchString in _currentClassname)}}) then { _rightPanelCtrl lnbDeleteRow _lbIndex; - } else { - _lbIndex = _lbIndex + 1; }; - _itemsToGo = _itemsToGo - 1; }; - _rightPanelCtrl lnbSetCurSelRow -1; + + // Try to select previously selected item again, otherwise select nothing + if (_selectedItemIndex != -1) then { + private _index = -1; + + // Try to find previously selected item in panel + for "_lbIndex" from 0 to (lnbSize _rightPanelCtrl select 0) - 1 do { + if ((_rightPanelCtrl lnbText [_lbIndex, 1]) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + // Select old item if found, otherwise don't select anything + _rightPanelCtrl lnbSetCurSelRow _index; + } else { + _rightPanelCtrl lnbSetCurSelRow -1; + }; }; [_display, nil, nil, configNull] call FUNC(itemInfo); } else { - - if !(GVAR(lastSearchTextLeft) isEqualTo "" || {(_textString find GVAR(lastSearchTextLeft)) == 0}) then {//don't refill if there is no need + // Left panel search bar + // Don't refill if there is no need + if (GVAR(lastSearchTextLeft) != "" && {(_searchString find GVAR(lastSearchTextLeft)) != 0}) then { [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); }; - GVAR(lastSearchTextLeft) = _textString; - if (count _textString == 0) exitWith {}; + + GVAR(lastSearchTextLeft) = _searchString; + + // If nothing searched, quit here + if (_searchString == "") exitWith {}; private _leftPanelCtrl = _display displayCtrl IDC_leftTabContent; + _searchString = toLower _searchString; + + // Get the currently selected item in panel + private _selectedItemIndex = lbCurSel _leftPanelCtrl; + private _selectedItem = ""; + + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _leftPanelCtrl lbText _selectedItemIndex; + }; + + private _currentDisplayName = ""; + private _currentClassname = ""; - private _itemsToGo = (lbSize _leftPanelCtrl); - private _lbIndex = 0; - while {_itemsToGo > 0} do { - private _currentData = _leftPanelCtrl lbText _lbIndex; - private _currentClassname = _leftPanelCtrl lbData _lbIndex; + // Go through all items in panel and see if they need to be deleted or not + for "_lbIndex" from (lbSize _leftPanelCtrl) - 1 to 0 step -1 do { + _currentDisplayName = toLower (_leftPanelCtrl lbText _lbIndex); + _currentClassname = toLower (_leftPanelCtrl lbData _lbIndex); - if ((_currentData isEqualTo "") || {(((toUpper _currentData) find (toUpper _textString)) == -1) && {((toUpper _currentClassname) find (toUpper _textString)) == -1}}) then { + // Remove item in panel if it doesn't match search, skip otherwise + if ((_currentDisplayName == "") || {!(_searchString in _currentDisplayName) && {!(_searchString in _currentClassname)}}) then { _leftPanelCtrl lbDelete _lbIndex; - } else { - _lbIndex = _lbIndex + 1; }; - _itemsToGo = _itemsToGo - 1; }; - _leftPanelCtrl lbSetCurSel -1; + + // Try to select previously selected item again, otherwise select nothing + if (_selectedItemIndex != -1) then { + private _index = -1; + + for "_lbIndex" from 0 to (lbSize _leftPanelCtrl) - 1 do { + if ((_leftPanelCtrl lbText _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + _leftPanelCtrl lbSetCurSel _index; + } else { + _leftPanelCtrl lbSetCurSel -1; + }; + [_display, nil, nil, configNull] call FUNC(itemInfo); }; diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf index 56d503423a4..4524cb7cb51 100644 --- a/addons/arsenal/functions/fnc_handleStats.sqf +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -27,7 +27,7 @@ private _hideUnusedFnc = { params ["_numbers"]; { - private _statsTitleCtrl = _display displayCtrl (5101 + ((_x - 1) * 4)); + private _statsTitleCtrl = _display displayCtrl (IDC_statsTitle1 + ((_x - 1) * 4)); private _statsTitleIDC = ctrlIDC _statsTitleCtrl; private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); @@ -47,7 +47,6 @@ private _hideUnusedFnc = { }; if (!isNil "_itemCfg") then { - private _handleStatsFnc = { params ["_statsIndex", "_leftPanel"]; @@ -59,7 +58,6 @@ if (!isNil "_itemCfg") then { } params ["_isLeftPanel", "_statsArray", "_currentPage"]; private _statsList = _statsArray select _currentPage; - private _statsCount = 0; // Handle titles, bars and text @@ -70,7 +68,7 @@ if (!isNil "_itemCfg") then { _bools params ["_showBar", "_showText"]; _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; - private _statsTitleCtrl = _display displayCtrl (5101 + _forEachIndex * 4); + private _statsTitleCtrl = _display displayCtrl (IDC_statsTitle1 + _forEachIndex * 4); private _statsTitleIDC = ctrlIDC _statsTitleCtrl; private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); @@ -151,7 +149,6 @@ if (!isNil "_itemCfg") then { }; if (ctrlIDC _control == IDC_leftTabContent) then { - if ([IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia] find GVAR(currentLeftPanel) > -1) then { [[1, 2, 3, 4, 5]] call _hideUnusedFnc; @@ -227,7 +224,6 @@ if (!isNil "_itemCfg") then { }; }; } else { - [[1, 2, 3, 4, 5]] call _hideUnusedFnc; _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, diff --git a/addons/arsenal/functions/fnc_initBox.sqf b/addons/arsenal/functions/fnc_initBox.sqf index 1343a20f633..51094c2a1f1 100644 --- a/addons/arsenal/functions/fnc_initBox.sqf +++ b/addons/arsenal/functions/fnc_initBox.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Initialize a box / object for arsenal. * * Arguments: @@ -22,40 +22,34 @@ params [["_object", objNull, [objNull]], ["_items", true, [[], true]], ["_global if (isNull _object) exitWith {}; -if (isNil QGVAR(EHIDArray)) then { - GVAR(EHIDArray) = []; -}; - -if (_global && {isMultiplayer} && {{_object in _x} count GVAR(EHIDArray) == 0}) then { +if (_global && {isMultiplayer} && {isNil {_object getVariable QGVAR(initBoxJIP)}}) then { + private _id = [QGVAR(initBox), [_object, _items, false]] call CBA_fnc_globalEventJIP; - private _ID = [QGVAR(initBox), [_object, _items, false]] call CBA_fnc_globalEventJIP; - [_ID, _object] call CBA_fnc_removeGlobalEventJIP; + // Remove JIP EH if object is deleted + [_id, _object] call CBA_fnc_removeGlobalEventJIP; - GVAR(EHIDArray) pushBack [_ID, _object]; - publicVariable QGVAR(EHIDArray); + // Save JIP ID + _object setVariable [QGVAR(initBoxJIP), _id, true]; } else { - - if ({(_x select 0) select 0 isEqualTo QGVAR(interaction)} count (_object getVariable [QEGVAR(interact_menu,actions), []]) == 0) then { - - private _action = [ - QGVAR(interaction), - localize "STR_A3_Arsenal", - "", - { - params ["_target", "_player"]; - - [_target, _player] call FUNC(openBox); - }, - { - params ["_target", "_player"]; - - [_player, _target] call EFUNC(common,canInteractWith) - }, - {}, - [] - ] call EFUNC(interact_menu,createAction); - [_object, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); - - [_object, _items, false] call FUNC(addVirtualItems); - }; + // Only add interaction if there isn't one already present + if (((_object getVariable [QEGVAR(interact_menu,actions), []]) findIf {((_x select 0) select 0) == QGVAR(interaction)}) != -1) exitWith {}; + + private _action = [ + QGVAR(interaction), + localize "STR_A3_Arsenal", + "", + { + params ["_target", "_player"]; + + [_target, _player] call FUNC(openBox); + }, + { + params ["_target", "_player"]; + + [_player, _target] call EFUNC(common,canInteractWith) + } + ] call EFUNC(interact_menu,createAction); + [_object, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); + + [_object, _items, false] call FUNC(addVirtualItems); }; diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf index 85a848c3bd8..e0643b49818 100644 --- a/addons/arsenal/functions/fnc_itemInfo.sqf +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -1,7 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Update arsenal's info box. * * Arguments: @@ -16,60 +17,55 @@ * Public: No */ -params ["_display", "_control", "_curSel" ,"_itemCfg"]; +params ["_display", "_control", "_curSel", "_itemCfg"]; private _ctrlInfo = _display displayCtrl IDC_infoBox; 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)); - - private _ctrlInfoAuthor = _display displayctrl IDC_infoAuthor; - _ctrlInfoAuthor ctrlSetText ""; + (_display displayCtrl IDC_infoName) ctrlSetText ([_control lbText _curSel, _control lnbText [_curSel, 1]] select (ctrlType _control == CT_LISTNBOX)); private _itemAuthor = getText (_itemCfg >> "author"); - _ctrlInfoAuthor ctrlSetText ([localize "STR_AUTHOR_UNKNOWN", format [localize "STR_FORMAT_AUTHOR_SCRIPTED",_itemAuthor]] select (_itemAuthor != "")); + (_display displayctrl IDC_infoAuthor) ctrlSetText ([localize "STR_AUTHOR_UNKNOWN", format [localize "STR_FORMAT_AUTHOR_SCRIPTED", _itemAuthor]] select (_itemAuthor != "")); // DLC / mod icon private _ctrlDLC = _display displayctrl IDC_DLCIcon; private _ctrlDLCBackground = _display displayctrl IDC_DLCBackground; - private _dlc = _itemCfg call GETDLC; + private _dlc = _itemCfg call EFUNC(common,getAddon); + if (_dlc != "") then { + (modParams [_dlc, ["name", "logo", "logoOver"]]) params ["_name", "_logo", "_logoOver"]; - private _dlcParams = modParams [_dlc, ["name", "logo", "logoOver"]]; - _dlcParams params ["_name", "_logo", "_logoOver"]; - private _appId = getnumber (configfile >> "CfgMods" >> _dlc >> "appId"); + _ctrlDLC ctrlSetTooltip _name; + _ctrlDLC ctrlSetText _logo; + _ctrlDLCBackground ctrlSetFade 0; + _ctrlDLC ctrlSetFade 0; - _ctrlDLC ctrlsettooltip _name; - _ctrlDLC ctrlsettext _logo; - _ctrlDLCBackground ctrlsetfade 0; - _ctrlDLC ctrlsetfade 0; - if (_appId > 0) then { - _ctrlDLC ctrlseteventhandler ["mouseexit",format ["(_this select 0) ctrlsettext '%1';",_logo]]; - _ctrlDLC ctrlseteventhandler ["mouseenter",format ["(_this select 0) ctrlsettext '%1';",_logoOver]]; - _ctrlDLC ctrlseteventhandler [ - "buttonclick", - format ["uiNamespace setvariable ['RscDisplayDLCPreview_dlc','%1']; ctrlparent (_this select 0) createDisplay 'RscDisplayDLCPreview';", _dlc] + // If an item is from a DLC, set it so when you press the icon on the bottom right it opens the DLC page + if ((getNumber (configfile >> "CfgMods" >> _dlc >> "appId")) > 0) then { + _ctrlDLC ctrlSetEventHandler ["mouseExit", format ["(_this select 0) ctrlSetText '%1';", _logo]]; + _ctrlDLC ctrlSetEventHandler ["mouseEnter", format ["(_this select 0) ctrlSetText '%1';", _logoOver]]; + _ctrlDLC ctrlSetEventHandler [ + "buttonClick", + format ["uiNamespace setVariable ['RscDisplayDLCPreview_dlc','%1']; ctrlParent (_this select 0) createDisplay 'RscDisplayDLCPreview';", _dlc] ]; } else { - _ctrlDLC ctrlRemoveAllEventHandlers "buttonclick"; - _ctrlDLC ctrlRemoveAllEventHandlers "mouseexit"; - _ctrlDLC ctrlRemoveAllEventHandlers "mouseenter"; + _ctrlDLC ctrlRemoveAllEventHandlers "mouseExit"; + _ctrlDLC ctrlRemoveAllEventHandlers "mouseEnter"; + _ctrlDLC ctrlRemoveAllEventHandlers "buttonClick"; }; } else { - _ctrlDLC ctrlsetfade 1; - _ctrlDLCBackground ctrlsetfade 1; + _ctrlDLC ctrlSetFade 1; + _ctrlDLCBackground ctrlSetFade 1; }; - _ctrlDLC ctrlcommit 0; - _ctrlDLCBackground ctrlcommit 0; + _ctrlDLC ctrlCommit 0; + _ctrlDLCBackground ctrlCommit 0; } else { [QGVAR(displayStats), [_display, _control, -1, nil]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf index 220cb697f27..8b6e973ad82 100644 --- a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf +++ b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf @@ -27,7 +27,6 @@ private _renameButtonCtrl = _display displayCtrl IDC_buttonRename; // Update UI visual elements if (GVAR(currentLoadoutsTab) != -1) then { - private _previousCtrlBackground = _display displayCtrl (GVAR(currentLoadoutsTab) - 1); _previousCtrlBackground ctrlSetBackgroundColor [0, 0, 0, 0.8]; _previousCtrlBackground ctrlCommit 0; @@ -45,26 +44,36 @@ _control ctrlSetTextColor [0, 0, 0, 1]; _control ctrlCommit 0; switch (ctrlIDC _control) do { + // Local loadouts case IDC_buttonMyLoadouts: { - _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabMyLoadoutsText)); + _centerBoxTitleCtrl ctrlSetText LLSTRING(tabMyLoadoutsText); + + if (is3DEN) then { + _saveButtonCtrl ctrlSetTooltip format ["%1\n%2", LLSTRING(buttonSaveTooltip), LLSTRING(buttonSaveTooltip_shiftClick)]; + }; - if (is3den) then { _saveButtonCtrl ctrlSetTooltip format ["%1\n%2", localize LSTRING(buttonSaveTooltip), localize LSTRING(buttonSaveTooltip_shiftClick)]; }; _saveButtonCtrl ctrlEnable true; _saveButtonCtrl ctrlCommit 0; }; - + // Default loadouts case IDC_buttonDefaultLoadouts: { - _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabDefaultLoadoutsText)); + _centerBoxTitleCtrl ctrlSetText LLSTRING(tabDefaultLoadoutsText); - if (is3den) then { _saveButtonCtrl ctrlSetTooltip localize LSTRING(buttonSaveTooltip); }; - _saveButtonCtrl ctrlEnable (is3DEN); + if (is3DEN) then { + _saveButtonCtrl ctrlSetTooltip LLSTRING(buttonSaveTooltip); + }; + + _saveButtonCtrl ctrlEnable is3DEN; _saveButtonCtrl ctrlCommit 0; }; - + // Shared loadouts case IDC_buttonSharedLoadouts: { - _centerBoxTitleCtrl ctrlSetText (localize LSTRING(tabSharedLoadoutsText)); + _centerBoxTitleCtrl ctrlSetText LLSTRING(tabSharedLoadoutsText); + + if (is3DEN) then { + _saveButtonCtrl ctrlSetTooltip LLSTRING(buttonSaveTooltip); + }; - if (is3den) then { _saveButtonCtrl ctrlSetTooltip localize LSTRING(buttonSaveTooltip); }; _saveButtonCtrl ctrlEnable false; _saveButtonCtrl ctrlCommit 0; }; @@ -73,8 +82,9 @@ switch (ctrlIDC _control) do { { _x ctrlEnable false; _x ctrlCommit 0; -} foreach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; +} forEach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; +// Save new tab as current tab GVAR(currentLoadoutsTab) = ctrlIDC _control; [QGVAR(loadoutsTabChanged), [_display, _control]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_message.sqf b/addons/arsenal/functions/fnc_message.sqf index f3e6abb3e6c..6b7d564bb3e 100644 --- a/addons/arsenal/functions/fnc_message.sqf +++ b/addons/arsenal/functions/fnc_message.sqf @@ -19,6 +19,7 @@ params ["_display", "_message"]; private _messageBoxCtrl = _display displayCtrl IDC_message; private _handle = _messageBoxCtrl getVariable QGVAR(messageBoxHandle); +// Stop previous message being displayed if (!isNil "_handle") then { terminate _handle; }; @@ -26,29 +27,30 @@ if (!isNil "_handle") then { _handle = [_display, _messageBoxCtrl, time + 5, _message, FADE_DELAY] spawn { disableSerialization; - _this params ["_display", "_control", "_timer", "_message", "_delay"]; + params ["_display", "_control", "_timer", "_message", "_delay"]; + + // Refresh message box, in case previous message box is still shown + _control ctrlSetText _message; + _control ctrlSetFade 1; + _control ctrlCommit 0; + + _control ctrlSetFade 0; + _control ctrlCommit _delay; while {_timer >= time} do { - switch true do { - case (_display isEqualTo displayNull): { - terminate _thisScript; - }; - - case (round (_timer - time) == 5): { - _control ctrlSetText _message; - _control ctrlSetFade 1; - _control ctrlCommit 0; - - _control ctrlSetFade 0; - _control ctrlCommit _delay; - }; + // If the display has been closed, quit + if (isNull _display) then { + terminate _thisScript; }; uiSleep 1; }; + // Hide message box and finish _control ctrlSetFade 1; _control ctrlCommit _delay; + terminate _thisScript; }; + _messageBoxCtrl setVariable [QGVAR(messageBoxHandle), _handle]; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 754512f5d48..95b367717fc 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -14,13 +14,10 @@ (_this select 1) params ["", "_exitCode"]; -private _cameraData = [getposAtl GVAR(camera), (getposAtl GVAR(camera)) vectorFromTo (getposAtl GVAR(cameraHelper))]; - [QGVAR(displayClosed), []] call CBA_fnc_localEvent; removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; if (is3DEN) then { - private _centerOriginParent = objectParent GVAR(centerOrigin); if !(isNull _centerOriginParent) then { @@ -31,11 +28,14 @@ if (is3DEN) then { // Apply the loadout from the dummy to all selected units if (_exitCode == 1) then { + private _extendedLoadout = GVAR(center) call FUNC(getLoadout); + private _objects = get3DENSelected "object"; + { - [_x, GVAR(center) call FUNC(getLoadout)] call CBA_fnc_setLoadout; - } foreach (get3DENSelected "object"); + [_x, _extendedLoadout] call CBA_fnc_setLoadout; + } forEach _objects; - save3DENInventory (get3DENSelected "object"); + save3DENInventory _objects; }; deleteVehicle GVAR(light); @@ -44,21 +44,21 @@ if (is3DEN) then { GVAR(centerOrigin) = nil; GVAR(light) = nil; - get3DENCamera cameraEffect ["internal","back"]; - ["ShowInterface",true] call bis_fnc_3DENInterface; - GVAR(visionMode) call bis_fnc_3DENVisionMode; + get3DENCamera cameraEffect ["Internal", "BACK"]; + ["ShowInterface", true] call BIS_fnc_3DENInterface; + GVAR(visionMode) call BIS_fnc_3DENVisionMode; } else { // Select correct weapon - switch GVAR(selectedWeaponType) do { - case 0: {GVAR(center) selectWeapon primaryWeapon GVAR(center);}; - case 1: {GVAR(center) selectWeapon secondaryWeapon GVAR(center);}; - case 2: {GVAR(center) selectWeapon handgunWeapon GVAR(center);}; + switch (GVAR(selectedWeaponType)) do { + case 0: {GVAR(center) selectWeapon (primaryWeapon GVAR(center))}; + case 1: {GVAR(center) selectWeapon (secondaryWeapon GVAR(center))}; + case 2: {GVAR(center) selectWeapon (handgunWeapon GVAR(center))}; }; - if (!(isnull curatorCamera) && {ACE_player == player}) then { - curatorcamera cameraEffect ["internal","back"]; + if (!isNull curatorCamera && {ACE_player == player}) then { + curatorCamera cameraEffect ["Internal", "BACK"]; } else { - GVAR(camera) cameraEffect ["terminate","back"]; + GVAR(camera) cameraEffect ["Terminate", "BACK"]; }; }; @@ -80,12 +80,13 @@ if (!isNull curatorCamera) then { curatorCamera setVectorDirAndUp _dirAndUp; }; -if (isMultiplayer) then { - [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(center) + "_face"] call CBA_fnc_globalEventJIP; - [QGVAR(center) + "_face", GVAR(center)] call CBA_fnc_removeGlobalEventJIP; +// Make face and voice selection JIP compatible; 3DEN doesn't need this though +if (isMultiplayer && {!is3DEN}) then { + private _id = [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(centerFace_) + netId GVAR(center)] call CBA_fnc_globalEventJIP; + [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; - [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(center) + "_voice"] call CBA_fnc_globalEventJIP; - [QGVAR(center) + "_voice", GVAR(center)] call CBA_fnc_removeGlobalEventJIP; + _id = [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(centerVoice_) + netId GVAR(center)] call CBA_fnc_globalEventJIP; + [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; }; GVAR(currentBox) = objNull; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index c69c7fbb171..85420b10cc5 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -1,13 +1,13 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * onLoad EH for arsenal. * * Arguments: * 0: Ignored * 1: Arguments - * 1.1: Arsenal display + * 1.1: Arsenal display * * Return Value: * None @@ -23,7 +23,7 @@ if (isNil QGVAR(center)) then { GVAR(center) = player; }; -GVAR(mouseButtonState) = [[],[]]; +GVAR(mouseButtonState) = [[], []]; if (isNil QGVAR(sharedLoadoutsNamespace)) then { GVAR(sharedLoadoutsNamespace) = true call CBA_fnc_createNamespace; @@ -36,168 +36,128 @@ if (isNil {GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars)}) if (isNil QGVAR(defaultLoadoutsList)) then { if (is3DEN) then { - GVAR(defaultLoadoutsList) = (QGVAR(DummyCategory) get3DENMissionAttribute QGVAR(DefaultLoadoutsListAttribute)); + GVAR(defaultLoadoutsList) = QGVAR(DummyCategory) get3DENMissionAttribute QGVAR(DefaultLoadoutsListAttribute); } else { GVAR(defaultLoadoutsList) = []; }; }; if (isNil QGVAR(virtualItems)) then { - GVAR(virtualItems) = [[[], [], []], [[], [], [], []], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]; + GVAR(virtualItems) = EMPTY_VIRTUAL_ARSENAL; }; -GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], []]; - GVAR(currentFace) = face GVAR(center); GVAR(currentVoice) = speaker GVAR(center); -GVAR(currentInsignia) = GVAR(center) param [0, objNull, [objNull]] getVariable ["BIS_fnc_setUnitInsignia_class", ""]; +GVAR(currentInsignia) = GVAR(center) call BIS_fnc_getUnitInsignia; 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(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]; -// Cache assignedItems -private _assignedItems = (getUnitLoadout GVAR(center)) select 9; - // Add the items the player has to virtualItems -for "_index" from 0 to 14 do { - switch (_index) do { - // primary, secondary, handgun weapons - case IDX_VIRT_WEAPONS: { - private _array = LIST_DEFAULTS select _index; - - if ((_array select 0) isNotEqualTo "") then { - ((GVAR(virtualItems) select _index) select 0) pushBackUnique (_array select 0); - }; - - if ((_array select 1) isNotEqualTo "") then { - ((GVAR(virtualItems) select _index) select 1) pushBackUnique (_array select 1); - }; - - if ((_array select 2) isNotEqualTo "") then { - ((GVAR(virtualItems) select _index) select 2) pushBackUnique (_array select 2); +{ + switch (_forEachIndex) do { + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + _x params [["_weapon", ""], ["_muzzle", ""], ["_flashlight", ""], ["_optics", ""], ["_primaryMagazine", []], ["_secondaryMagazine", []], ["_bipod", ""]]; + + // Add weapon + if (_weapon != "") then { + _weapon = _weapon call EFUNC(common,baseWeapon); + + if (_weapon != "") then { + // If bino, add it in a different place than regular weapons + if (_forEachIndex != IDX_LOADOUT_BINO) then { + (GVAR(virtualItems) select IDX_VIRT_WEAPONS select _forEachIndex) pushBackUnique _weapon; + } else { + (GVAR(virtualItems) select IDX_VIRT_BINO) pushBackUnique _weapon; + }; + }; }; - }; - - // Accs for the weapons above - case IDX_VIRT_ATTACHEMENTS: { - private _array = LIST_DEFAULTS select _index; - _array params ["_accsArray", "_magsArray"]; + // Add weapon attachments { - private _subIndex = _forEachIndex; - - { - if (_x != "") then { - (GVAR(virtualItems) select _index) select ([2, 1, 0, 3] select _forEachIndex) pushBackUnique _x; - }; - } forEach _x; - } forEach _accsArray; + if (_x != "") then { + ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _forEachIndex) pushBackUnique _x; + }; + } forEach [_optics, _flashlight, _muzzle, _bipod]; + // Add magazines { - if (_x isNotEqualTo []) then { - - if (_x select 0 != "") then { - (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) pushBackUnique (_x select 0); - }; - - if (count _x > 1 && {_x select 1 != ""}) then { - (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) pushBackUnique (_x select 1); - }; + // Check if there is a magazine and if it has some ammo + if ((_x param [0, ""]) != "" && {(_x select 1) > 0}) then { + (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) pushBackUnique (_x select 0); }; - } forEach _magsArray; + } forEach [_primaryMagazine, _secondaryMagazine]; }; + // Uniform + case IDX_LOADOUT_UNIFORM: { + _x params [["_containerClass", ""]]; - // Assigned items - case IDX_VIRT_MAP: { (GVAR(virtualItems) select _index) pushBackUnique (_assignedItems select 0) }; - case IDX_VIRT_COMMS: { (GVAR(virtualItems) select _index) pushBackUnique (_assignedItems select 1) }; - case IDX_VIRT_RADIO: { (GVAR(virtualItems) select _index) pushBackUnique (_assignedItems select 2) }; - case IDX_VIRT_COMPASS: { (GVAR(virtualItems) select _index) pushBackUnique (_assignedItems select 3) }; - case IDX_VIRT_WATCH: { (GVAR(virtualItems) select _index) pushBackUnique (_assignedItems select 4) }; - - - // Inventory items - case IDX_VIRT_ITEMS_ALL: { - call FUNC(updateUniqueItemsList); - }; - - // The rest - default { - private _array = (LIST_DEFAULTS select _index) select {_x isNotEqualTo ""}; - if (_array isNotEqualTo []) then { - {(GVAR(virtualItems) select _index) pushBackUnique _x} forEach _array; + if (_containerClass != "") then { + (GVAR(virtualItems) select IDX_VIRT_UNIFORM) pushBackUnique _containerClass; }; }; - }; -}; + // Vest + case IDX_LOADOUT_VEST: { + _x params [["_containerClass", ""]]; -// Fill current items -for "_index" from 0 to 15 do { - switch (_index) do { - case 0; - case 1; - case 2:{ - GVAR(currentItems) set [_index, ((LIST_DEFAULTS select 0) select _index)]; + if (_containerClass != "") then { + (GVAR(virtualItems) select IDX_CURR_VEST) pushBackUnique _containerClass; + }; }; - case 3; - case 4; - case 5; - case 6; - case 7; - case 8; - case 9: { - GVAR(currentItems) set [_index, (LIST_DEFAULTS select _index) select 0]; + // Backpack + case IDX_LOADOUT_BACKPACK: { + _x params [["_containerClass", ""]]; + if (_containerClass != "") then { + (GVAR(virtualItems) select IDX_CURR_BACKPACK) pushBackUnique _containerClass; + }; }; - case 10: { - {(GVAR(currentItems) select 15) pushBack _x} forEach (uniformItems GVAR(center)); - }; - case 11: { - {(GVAR(currentItems) select 16) pushBack _x} forEach (vestItems GVAR(center)); - }; - case 12: { - {(GVAR(currentItems) select 17) pushBack _x} forEach (backpackItems GVAR(center)); - }; - case 13: { - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + (primaryWeaponMagazine GVAR(center))]; + // Helmet + case IDX_LOADOUT_HEADGEAR: { + if (_x != "") then { + (GVAR(virtualItems) select IDX_VIRT_HEADGEAR) pushBackUnique _x; + }; }; - case 14: { - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + (secondaryWeaponMagazine GVAR(center))]; + // Facewear + case IDX_LOADOUT_GOGGLES: { + if (_x != "") then { + (GVAR(virtualItems) select IDX_VIRT_GOGGLES) pushBackUnique _x; + }; }; - case 15: { - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + (handgunMagazine GVAR(center))]; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + { + // Order of storing virtualItems is different than what getUnitLoadout returns, so do some math + if (_x != "") then { + (GVAR(virtualItems) select (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex))) pushBackUnique _x; + }; + } forEach _x; }; }; -}; +} forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout -{ - switch (_forEachIndex) do { - case 0: { // Map - GVAR(currentItems) set [10, _x]; - }; - case 1: { // GPS - GVAR(currentItems) set [14, _x]; - }; - case 2: { // Radio - GVAR(currentItems) set [12, _x]; - }; - case 3: { // Compass - GVAR(currentItems) set [11, _x]; - }; - case 4: { // Watch - GVAR(currentItems) set [13, _x]; - }; - }; -} forEach _assignedItems; +// Update current item list +call FUNC(updateCurrentItemsList); + +// This takes care of items that aren't available in the arsenal (either wrong tab or arsenal doesn't have it whitelisted) +call FUNC(updateUniqueItemsList); -GVAR(currentWeaponType) = switch true do { - case (currentWeapon GVAR(center) == GVAR(currentItems) select 0): {0}; - case (currentWeapon GVAR(center) == GVAR(currentItems) select 1): {1}; - case (currentWeapon GVAR(center) == GVAR(currentItems) select 2): {2}; +// Get the type of the current weapon +private _currentWeapon = currentWeapon GVAR(center); + +GVAR(currentWeaponType) = switch (true) do { + case (_currentWeapon == (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON)): {0}; + case (_currentWeapon == (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON)): {1}; + case (_currentWeapon == (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON)): {2}; default {-1}; }; @@ -250,7 +210,7 @@ if (isMultiplayer) then { }; //--------------- Camera prep -cutText ["","plain"]; +cutText ["", "PLAIN"]; showCommandingMenu ""; GVAR(cameraView) = cameraView; @@ -260,73 +220,71 @@ GVAR(center) switchCamera "internal"; private _mouseAreaCtrl = _display displayCtrl IDC_mouseArea; ctrlSetFocus _mouseAreaCtrl; +private _centerPos = position GVAR(center); + // 3DEN support, lifted from BIS_fnc_arsenal if (is3DEN) then { - GVAR(centerOrigin) = GVAR(center); GVAR(centerOrigin) hideObject true; private _centerOriginParent = objectParent GVAR(centerOrigin); + if !(isNull _centerOriginParent) then { _centerOriginParent hideObject true; }; - private _centerPos = position GVAR(centerOrigin); - - GVAR(center) = createAgent [typeOf GVAR(centerOrigin), position GVAR(centerOrigin), [], 0, "none"]; - GVAR(center) setPosAtl getPosAtl GVAR(centerOrigin); + GVAR(center) = createAgent [typeOf GVAR(centerOrigin), _centerPos, [], 0, "none"]; + GVAR(center) setPosATL getPosATL GVAR(centerOrigin); GVAR(center) setDir (getDir GVAR(centerOrigin)); GVAR(center) switchMove animationState GVAR(centerOrigin); - GVAR(center) switchAction "playerstand"; + GVAR(center) switchAction "playerStand"; GVAR(center) enableSimulation false; - GVAR(center) setUnitLoadout (getUnitLoadout GVAR(centerOrigin)); - GVAR(center) setFace GVAR(currentFace); - GVAR(center) setSpeaker GVAR(currentVoice); + [GVAR(center), GVAR(centerOrigin) call FUNC(getLoadout)] call CBA_fnc_setLoadout; //--- Create light for night editing (code based on BIS_fnc_3DENFlashlight) - private _intensity = 1; GVAR(light) = "#lightpoint" createVehicle _centerPos; - GVAR(light) setLightBrightness _intensity; - GVAR(light) setLightAmbient [1,1,1]; - GVAR(light) setLightColor [0,0,0]; - GVAR(light) lightAttachObject [GVAR(centerOrigin), [0, 0, -_intensity * 7]]; + GVAR(light) setLightBrightness 1; + GVAR(light) setLightAmbient [1, 1, 1]; + GVAR(light) setLightColor [0, 0, 0]; + GVAR(light) lightAttachObject [GVAR(centerOrigin), [0, 0, -7]]; //--- Use the same vision mode as in Eden - GVAR(visionMode)= -2 call bis_fnc_3DENVisionMode; - ["ShowInterface",false] spawn bis_fnc_3DENInterface; - if (get3denactionstate "togglemap" > 0) then {do3DENAction "togglemap";}; + GVAR(visionMode) = -2 call BIS_fnc_3DENVisionMode; + ["ShowInterface", false] spawn BIS_fnc_3DENInterface; + + if (get3DENActionState "toggleMap" > 0) then { + do3DENAction "toggleMap"; + }; + + private _ctrl = controlNull; { - private _ctrl = _display displayctrl _x; + _ctrl = _display displayCtrl _x; + _ctrl ctrlEnable false; _ctrl ctrlSetFade 0.6; _ctrl ctrlCommit 0; - } forEach [ - IDC_buttonFace, - IDC_buttonVoice, - IDC_buttonInsignia - ]; + } forEach [IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia]; _buttonCloseCtrl = _display displayCtrl IDC_menuBarClose; _buttonCloseCtrl ctrlSetText (localize "str_ui_debug_but_apply"); } else { - GVAR(centerNotPlayer) = (GVAR(center) != player); + GVAR(centerNotPlayer) = GVAR(center) != player; if (currentVisionMode ACE_Player == 1) then { GVAR(center) action ["NVGogglesOff", GVAR(center)]; }; + private _ctrl = controlNull; + { - private _ctrl = _display displayCtrl _x; + _ctrl = _display displayCtrl _x; + _ctrl ctrlEnable GVAR(enableIdentityTabs); _ctrl ctrlSetFade ([0.6, 0] select GVAR(enableIdentityTabs)); _ctrl ctrlCommit 0; - } forEach [ - IDC_buttonFace, - IDC_buttonVoice, - IDC_buttonInsignia - ]; + } forEach [IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia]; }; //--------------- Prepare the left panel @@ -348,26 +306,28 @@ GVAR(rightTabLnBFocus) = false; //--------------- Init camera if (isNil QGVAR(cameraPosition)) then { - GVAR(cameraPosition) = [5,0,0,[0,0,0.85]]; + GVAR(cameraPosition) = [5, 0, 0, [0, 0, 0.85]]; }; // Save curator camera state so camera position and direction are not modified while using arsenal -if (!isNull curatorCamera) then { - GVAR(curatorCameraData) = [getPosASL curatorCamera, [vectorDir curatorCamera, vectorUp curatorCamera]]; +private _curatorCamera = curatorCamera; + +if (!isNull _curatorCamera) then { + GVAR(curatorCameraData) = [getPosASL _curatorCamera, [vectorDir _curatorCamera, vectorUp _curatorCamera]]; }; -GVAR(cameraHelper) = createAgent ["Logic", position GVAR(center) ,[] ,0 ,"none"]; +GVAR(cameraHelper) = createAgent ["Logic", _centerPos, [], 0, "none"]; GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; -GVAR(camera) = "camera" camCreate position GVAR(center); -GVAR(camera) cameraEffect ["internal","back"]; -GVAR(camera) camPrepareFocus [-1,-1]; +GVAR(camera) = "camera" camCreate _centerPos; +GVAR(camera) cameraEffect ["internal", "back"]; +GVAR(camera) camPrepareFocus [-1, -1]; GVAR(camera) camPrepareFov 0.35; GVAR(camera) camCommitPrepared 0; showCinemaBorder false; -["#(argb,8,8,3)color(0,0,0,1)",false,nil,0,[0,0.5]] call bis_fnc_textTiles; +["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0, [0, 0.5]] call BIS_fnc_textTiles; //--------------- Reset camera pos -[nil, [controlNull,0,0]] call FUNC(handleMouse); -GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D",{ [] call FUNC(updateCamPos) }]; +[nil, [controlNull, 0, 0]] call FUNC(handleMouse); +GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D", {call FUNC(updateCamPos)}]; diff --git a/addons/arsenal/functions/fnc_onKeyDown.sqf b/addons/arsenal/functions/fnc_onKeyDown.sqf index 2bd8e0ac7b2..bc110f3f64b 100644 --- a/addons/arsenal/functions/fnc_onKeyDown.sqf +++ b/addons/arsenal/functions/fnc_onKeyDown.sqf @@ -2,12 +2,12 @@ #include "..\defines.hpp" #include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles keyboard inputs in arsenal. * * Arguments: * 0: Arsenal display - * 1: Key being pressed + * 1: Key being pressed * 2: Shift state * 3: Ctrl state * 4: Alt state @@ -25,12 +25,14 @@ GVAR(shiftState) = _shiftState; private _return = true; private _loadoutsDisplay = findDisplay IDD_loadouts_display; -if (_loadoutsDisplay isNotEqualTo displayNull) then { - if !(GVAR(loadoutsSearchbarFocus)) then { - switch true do { +// If in loadout screen +if (!isNull _loadoutsDisplay) then { + // If loadout search bar isn't focussed + if (!GVAR(loadoutsSearchbarFocus)) then { + switch (true) do { // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; + _display closeDisplay IDC_CANCEL; }; // Search field case (_keyPressed == DIK_F && {_ctrlState}): { @@ -38,48 +40,37 @@ if (_loadoutsDisplay isNotEqualTo displayNull) then { }; }; } else { - switch true do { + // If loadout search bar is focussed + switch (true) do { + // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; - }; - case (_keyPressed == DIK_BACKSPACE): { - _return = false; + _display closeDisplay IDC_CANCEL; }; + // Search case (_keyPressed == DIK_NUMPADENTER); case (_keyPressed == DIK_RETURN): { [_loadoutsDisplay, _loadoutsDisplay displayCtrl IDC_loadoutsSearchbar] call FUNC(handleLoadoutsSearchBar); }; + case (_keyPressed == DIK_BACKSPACE); case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { _return = false; }; }; }; - switch true do { - case (_keyPressed == DIK_C && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_V && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_A && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_X && {_ctrlState}): { - _return = false; - }; + switch (true) do { + case (_keyPressed in [DIK_C, DIK_V, DIK_A, DIK_X] && {_ctrlState}); case (GVAR(loadoutsPanelFocus) && {_keyPressed in [DIK_UP, DIK_DOWN]}): { _return = false; }; }; } else { - + // If in arsenal and no search bar is selected if (!GVAR(leftSearchbarFocus) && {!GVAR(rightSearchbarFocus)}) then { - - switch true do { + switch (true) do { // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; + _display closeDisplay IDC_CANCEL; }; // Hide button case (_keyPressed == DIK_BACKSPACE): { @@ -88,7 +79,7 @@ if (_loadoutsDisplay isNotEqualTo displayNull) then { // Export button / export classname case (_keyPressed == DIK_C && {_ctrlState}): { if (GVAR(leftTabFocus) || {GVAR(rightTabFocus)} || {GVAR(rightTabLnBFocus)}) then { - switch true do { + switch (true) do { case (GVAR(leftTabFocus)): { private _control = (_display displayCtrl IDC_leftTabContent); _control lbData (lbCurSel _control) @@ -99,14 +90,14 @@ if (_loadoutsDisplay isNotEqualTo displayNull) then { }; case (GVAR(rightTabLnBFocus)): { private _control = (_display displayCtrl IDC_rightTabContentListnBox); - _control lnbData [(lnbCurSelRow _control), 0] + _control lnbData [lnbCurSelRow _control, 0] }; } params ["_className"]; "ace_clipboard" callExtension (_className + ";"); "ace_clipboard" callExtension "--COMPLETE--"; - [_display, localize LSTRING(exportedClassnameText)] call FUNC(message); + [_display, LLSTRING(exportedClassnameText)] call FUNC(message); } else { [_display] call FUNC(buttonExport); }; @@ -115,36 +106,37 @@ if (_loadoutsDisplay isNotEqualTo displayNull) then { case (_keyPressed == DIK_V && {_ctrlState}): { [_display] call FUNC(buttonImport); }; - // Search fields + // Focus search case (_keyPressed == DIK_F && {_ctrlState}): { ctrlSetFocus (_display displayCtrl IDC_leftSearchbar); }; // Switch vision mode - case (_keyPressed in (actionkeys "nightvision")): { + case (_keyPressed in (actionKeys "nightvision")): { if (isNil QGVAR(visionMode)) then { GVAR(visionMode) = 0; }; + GVAR(visionMode) = (GVAR(visionMode) + 1) % 3; - switch GVAR(visionMode) do { - //--- Normal + switch (GVAR(visionMode)) do { + // Normal case 0: { - camusenvg false; - false setCamUseTi 0; + camUseNVG false; + false setCamUseTI 0; }; - //--- NVG + // NVG case 1: { - camusenvg true; - false setCamUseTi 0; + camUseNVG true; + false setCamUseTI 0; }; - //--- TI + // TI default { - camusenvg false; - true setCamUseTi 0; + camUseNVG false; + true setCamUseTI 0; }; }; - playsound ["RscDisplayCurator_visionMode",true]; + playSound ["RscDisplayCurator_visionMode", true]; }; // Panel up down case (_keyPressed in [DIK_UP, DIK_DOWN]): { @@ -160,38 +152,29 @@ if (_loadoutsDisplay isNotEqualTo displayNull) then { }; }; } else { - switch true do { + // If in arsenal and a search bar is selected + switch (true) do { + // Close button case (_keyPressed == DIK_ESCAPE): { - _display closeDisplay 2; - }; - case (_keyPressed == DIK_BACKSPACE): { - _return = false; + _display closeDisplay IDC_CANCEL; }; + // Search case (_keyPressed == DIK_NUMPADENTER); case (_keyPressed == DIK_RETURN): { if (GVAR(leftSearchbarFocus)) then { [_display, _display displayCtrl IDC_leftSearchbar] call FUNC(handleSearchBar); }; + if (GVAR(rightSearchbarFocus)) then { [_display, _display displayCtrl IDC_rightSearchbar] call FUNC(handleSearchBar); }; }; - case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { - _return = false; - }; - case (_keyPressed == DIK_C && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_V && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_A && {_ctrlState}): { - _return = false; - }; - case (_keyPressed == DIK_X && {_ctrlState}): { + case (_keyPressed in [DIK_LEFT, DIK_RIGHT]); + case (_keyPressed == DIK_BACKSPACE); + case (_keyPressed in [DIK_C, DIK_V, DIK_A, DIK_X] && {_ctrlState}): { _return = false; }; - // Search fields + // Focus search fields case (_keyPressed == DIK_F && {_ctrlState}): { if (GVAR(rightSearchbarFocus)) then { ctrlSetFocus (_display displayCtrl IDC_leftSearchbar); diff --git a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf index 07af50139da..84912e6d6a1 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsClose.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsClose.sqf @@ -14,13 +14,11 @@ */ GVAR(currentLoadoutsTab) = nil; - -private _arsenalDisplay = findDisplay IDD_ace_arsenal; -private _mouseBlockCtrl = _arsenalDisplay displayCtrl IDC_mouseBlock; - GVAR(loadoutsSearchbarFocus) = nil; GVAR(loadoutsPanelFocus) = nil; +private _arsenalDisplay = findDisplay IDD_ace_arsenal; +private _mouseBlockCtrl = _arsenalDisplay displayCtrl IDC_mouseBlock; _mouseBlockCtrl ctrlEnable false; _mouseBlockCtrl ctrlCommit 0; @@ -28,4 +26,4 @@ _mouseBlockCtrl ctrlCommit 0; [QGVAR(loadoutsDisplayClosed), []] call CBA_fnc_localEvent; -[_arsenalDisplay , _arsenalDisplay displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); +[_arsenalDisplay, _arsenalDisplay displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf index eb72087f897..6e2965d60bf 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf @@ -7,7 +7,7 @@ * Arguments: * 0: Ignored * 1: Arguments - * 1.1: Loadouts display + * 1.1: Loadouts display * * Return Value: * None @@ -34,6 +34,7 @@ private _panelContentCtrl = _display displayCtrl IDC_contentPanel; _panelContentCtrl ctrlSetFontHeight (4.5 * GRID_H); _panelContentCtrl ctrlCommit 0; +// If default loadouts are disabled, disable button if !(GVAR(allowDefaultLoadouts)) then { private _buttonDefaultLoadoutsCtrl = _display displayCtrl IDC_buttonDefaultLoadouts; _buttonDefaultLoadoutsCtrl ctrlEnable false; @@ -44,6 +45,7 @@ if !(GVAR(allowDefaultLoadouts)) then { _buttonDefaultLoadoutsBackgroundCtrl ctrlCommit 0; }; +// If shared loadouts are disabled or it's singleplayer, disable button if !(GVAR(allowSharedLoadouts) && {isMultiplayer}) then { private _buttonShareLoadoutsCtrl = _display displayCtrl IDC_buttonSharedLoadouts; _buttonShareLoadoutsCtrl ctrlEnable false; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index be93fec83e3..05b0fd621d6 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -1,5 +1,6 @@ #include "script_component.hpp" #include "..\defines.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" /* * Author: Alganthe * Handles selection changes on the left panel. @@ -18,429 +19,631 @@ params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; -private _ctrlIDC = ctrlIDC _control; private _display = ctrlParent _control; -private _item = [_control lnbData [_curSel, 0], _control lbData _curSel] select !(ctrlType _control == 102); +private _item = [_control lbData _curSel, _control lnbData [_curSel, 0]] select (ctrlType _control == CT_LISTNBOX); -private _weaponDefaultRightPanel = _display displayCtrl IDC_buttonOptic; -private _selectCorrectPanelWeapon = [_weaponDefaultRightPanel, _display displayCtrl GVAR(currentRightPanel)] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}); - -private _containerDefaultRightPanel = _display displayCtrl IDC_buttonMisc; -private _selectCorrectPanelContainer = [_containerDefaultRightPanel, _display displayCtrl GVAR(currentRightPanel)] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ITEMS_IDCS]}); +// When having chosen a new category, see if the current right panel can be kept open, otherwise take default +private _selectCorrectPanelWeapon = [_display displayCtrl IDC_buttonOptic, _display displayCtrl GVAR(currentRightPanel)] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}); +private _selectCorrectPanelContainer = [_display displayCtrl IDC_buttonMisc, _display displayCtrl GVAR(currentRightPanel)] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ITEMS_IDCS]}); +// Remove all magazines from the previous weapon that aren't compatible with the new weapon private _fnc_clearPreviousWepMags = { - private _compatibleMagsBaseWeapon = [_baseWeapon, true] call CBA_fnc_compatibleMagazines; + private _compatibleMagsBaseWeapon = compatibleMagazines _baseWeapon; + // If nothing was selected, remove all magazines from the previous weapon if (_item != "") then { - _compatibleMagsBaseWeapon = _compatibleMagsBaseWeapon select {!(_x in _compatibleMags)}; + _compatibleMagsBaseWeapon = _compatibleMagsBaseWeapon - _compatibleMags; }; { GVAR(center) removeMagazines _x; - } foreach _compatibleMagsBaseWeapon; + } forEach _compatibleMagsBaseWeapon; + + // Update currentItems + private _loadout = getUnitLoadout GVAR(center); - GVAR(currentItems) set [15, uniformItems GVAR(center)]; - GVAR(currentItems) set [16, vestItems GVAR(center)]; - GVAR(currentItems) set [17, backpackItems GVAR(center)]; + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, (_loadout select IDX_LOADOUT_UNIFORM) param [1, []]]; + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, (_loadout select IDX_LOADOUT_VEST) param [1, []]]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, (_loadout select IDX_LOADOUT_BACKPACK) param [1, []]]; }; +// Check which right panel has changed switch (GVAR(currentLeftPanel)) do { + // Primary weapon + case IDC_buttonPrimaryWeapon: { + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) call EFUNC(common,baseWeapon); - case IDC_buttonPrimaryWeapon : { - private _baseWeapon = ((GVAR(currentItems) select 0) call bis_fnc_baseWeapon); - + // If nothing selected, remove primary weapon and its magazines if (_item == "") then { call _fnc_clearPreviousWepMags; GVAR(center) removeWeapon (primaryWeapon GVAR(center)); - GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; - GVAR(currentItems) set [0, _item]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON, ""]; TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 0) != _item && {_baseWeapon != _item}) then { - private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; - private _cfgMags = configFile >> "CfgMagazines"; - private _compatibleMags = ([_item, true] call CBA_fnc_compatibleMagazines) select { getNumber (_cfgMags >> _x >> "scope") == 2 }; + // Check if a new primary weapon was selected + if ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) != _item && {_baseWeapon != _item}) then { + // Get magazines that are compatible with the new weapon + private _compatibleMags = compatibleMagazines _item; + private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + // Remove all magazines from the previous weapon that aren't compatible with the new one call _fnc_clearPreviousWepMags; - [GVAR(center), _item] call CBA_fnc_addWeaponWithoutItems; - if (_compatibleMags isNotEqualTo []) then { - GVAR(center) addWeaponItem [_item, [_compatibleMags select 0], true]; + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = primaryWeaponItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); + + { + if !(_x in _availableAttachments) then { + GVAR(center) removePrimaryWeaponItem _x; + }; + } forEach _linkedItems; }; + // Add old attachments and magazines back if they are compatible { - if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { - GVAR(center) addPrimaryWeaponItem _x; + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; }; - } foreach (GVAR(currentItems) select 18); + } forEach (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS); + + // Add a magazine to the weapon itself if necessary + if ((primaryWeaponMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { + GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + }; - private _primaryMags = primaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; - GVAR(currentItems) set [0, _item]; + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_PRIMARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON, _item]; }; TOGGLE_RIGHT_PANEL_WEAPON + [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonHandgun : { - private _baseWeapon = ((GVAR(currentItems) select 2) call bis_fnc_baseWeapon); + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Handgun weapon + case IDC_buttonHandgun: { + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) call EFUNC(common,baseWeapon); + // If nothing selected, remove handgun weapon and its magazines if (_item == "") then { call _fnc_clearPreviousWepMags; GVAR(center) removeWeapon (handgunWeapon GVAR(center)); - GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; - GVAR(currentItems) set [2, _item]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON, ""]; TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 2) != _item && {_baseWeapon != _item}) then { - private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; - private _cfgMags = configFile >> "CfgMagazines"; - private _compatibleMags = ([_item, true] call CBA_fnc_compatibleMagazines) select { getNumber (_cfgMags >> _x >> "scope") == 2 }; + // Check if a new handgun weapon was selected + if ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) != _item && {_baseWeapon != _item}) then { + // Get magazines that are compatible with the new weapon + private _compatibleMags = compatibleMagazines _item; + private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + // Remove all magazines from the previous weapon that aren't compatible with the new one call _fnc_clearPreviousWepMags; - [GVAR(center), _item] call CBA_fnc_addWeaponWithoutItems; - if (_compatibleMags isNotEqualTo []) then { - GVAR(center) addWeaponItem [_item, [_compatibleMags select 0], true]; + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = handgunItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); + + { + if !(_x in _availableAttachments) then { + GVAR(center) removeHandgunItem _x; + }; + } forEach _linkedItems; }; + // Add old attachments and magazines back if they are compatible { - if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { - GVAR(center) addHandgunItem _x; + + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; }; - } foreach (GVAR(currentItems) select 20); + } forEach (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS); + + // Add a magazine to the weapon itself if necessary + if ((handgunMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { + GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + }; - private _handgunMags = handgunMagazine GVAR(center); - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; - GVAR(currentItems) set [2, _item]; + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON, _item]; }; TOGGLE_RIGHT_PANEL_WEAPON - [_display, [_selectCorrectPanelWeapon, _weaponDefaultRightPanel] select (GVAR(currentRightPanel) == IDC_buttonCurrentMag2)] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonSecondaryWeapon : { - private _baseWeapon = ((GVAR(currentItems) select 1) call bis_fnc_baseWeapon); + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Secondary weapon + case IDC_buttonSecondaryWeapon: { + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) call EFUNC(common,baseWeapon); + // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { call _fnc_clearPreviousWepMags; GVAR(center) removeWeapon (secondaryWeapon GVAR(center)); - GVAR(currentItems) set [18, ["", "", "", "", "", ""]]; - GVAR(currentItems) set [1, _item]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON, ""]; + TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 1) != _item && {_baseWeapon != _item}) then { - private _compatibleItems = (_item call bis_fnc_compatibleItems) apply {tolower _x}; - private _cfgMags = configFile >> "CfgMagazines"; - private _compatibleMags = ([_item, true] call CBA_fnc_compatibleMagazines) select { getNumber (_cfgMags >> _x >> "scope") == 2 }; + // Check if a new secondary weapon was selected + if ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) != _item && {_baseWeapon != _item}) then { + // Get magazines that are compatible with the new weapon + private _compatibleMags = compatibleMagazines _item; + private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + // Remove all magazines from the previous weapon that aren't compatible with the new one call _fnc_clearPreviousWepMags; - [GVAR(center), _item] call CBA_fnc_addWeaponWithoutItems; - if (_compatibleMags isNotEqualTo []) then { - GVAR(center) addWeaponItem [_item, [_compatibleMags select 0], true]; + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = secondaryWeaponItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); + + { + if !(_x in _availableAttachments) then { + GVAR(center) removeSecondaryWeaponItem _x; + }; + } forEach _linkedItems; }; + // Add old attachments and magazines back if they are compatible { - if (tolower _x in _compatibleItems || {_x in _compatibleMags}) then { - GVAR(center) addSecondaryWeaponItem _x; + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; }; - } foreach (GVAR(currentItems) select 19); + } forEach (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS); + + // Add a magazine to the weapon itself if necessary + if ((secondaryWeaponMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { + GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + }; - private _secondaryMags = secondaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; - GVAR(currentItems) set [1, _item]; + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON, _item]; }; TOGGLE_RIGHT_PANEL_WEAPON - [_display, [_selectCorrectPanelWeapon, _weaponDefaultRightPanel] select (GVAR(currentRightPanel) == IDC_buttonCurrentMag2)] call FUNC(fillRightPanel); + + [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - - case IDC_buttonHeadgear : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Headgear + case IDC_buttonHeadgear: { if (_item == "") then { removeHeadgear GVAR(center); - GVAR(currentItems) set [3, _item]; + GVAR(currentItems) set [IDX_CURR_HEADGEAR, ""]; } else { - if ((GVAR(currentItems) select 3) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_HEADGEAR) != _item) then { GVAR(center) addHeadgear _item; - GVAR(currentItems) set [3, _item]; + GVAR(currentItems) set [IDX_CURR_HEADGEAR, _item]; }; }; + + // Make unit switch to new item call FUNC(showItem); TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonUniform : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Uniform + case IDC_buttonUniform: { if (_item == "") then { + removeUniform GVAR(center); + + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, []]; + GVAR(currentItems) set [IDX_CURR_UNIFORM, ""]; - removeuniform GVAR(center); - GVAR(currentItems) set [15, []]; - GVAR(currentItems) set [4, _item]; TOGGLE_RIGHT_PANEL_HIDE } else { + if ((GVAR(currentItems) select IDX_CURR_UNIFORM) != _item) then { + // Get the unit's current loadout and just change the container + private _loadout = getUnitLoadout GVAR(center); + _loadout set [IDX_LOADOUT_UNIFORM, [_item, GVAR(currentItems) select IDX_CURR_UNIFORM_ITEMS]]; + GVAR(center) setUnitLoadout _loadout; + + private _uniformItems = uniformItems GVAR(center); + private _index = count _backpackItems - 1; + + // Remove any items that can't fit in the container (this prevents overloading) + while {loadUniform GVAR(center) > 1} do { + GVAR(center) removeItemFromUniform (_backpackItems select _index); + DEC(_index); + }; - if ((GVAR(currentItems) select 4) != _item) then { - GVAR(center) forceAddUniform _item; - - while {count uniformItems GVAR(center) > 0} do { - GVAR(center) removeItemFromUniform (uniformItems GVAR(center) select 0); - }; //--- Remove default config contents - - {GVAR(center) addItemtoUniform _x} foreach (GVAR(currentItems) select 15); - GVAR(currentItems) set [4, _item]; + GVAR(currentItems) set [IDX_CURR_UNIFORM, _item]; - [GVAR(center), ""] call bis_fnc_setUnitInsignia; - [GVAR(center), GVAR(currentInsignia)] call bis_fnc_setUnitInsignia; + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER + [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Vest case IDC_buttonVest: { if (_item == "") then { - removeVest GVAR(center); - GVAR(currentItems) set [16, []]; - GVAR(currentItems) set [5, _item]; + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, []]; + GVAR(currentItems) set [IDX_CURR_VEST, ""]; + TOGGLE_RIGHT_PANEL_HIDE } else { + if ((GVAR(currentItems) select IDX_CURR_VEST) != _item) then { + // Get the unit's current loadout and just change the container + private _loadout = getUnitLoadout GVAR(center); + _loadout set [IDX_LOADOUT_VEST, [_item, GVAR(currentItems) select IDX_CURR_VEST_ITEMS]]; + GVAR(center) setUnitLoadout _loadout; + + private _backpackItems = vestItems GVAR(center); + private _index = count _backpackItems - 1; + + // Remove any items that can't fit in the container (this prevents overloading) + while {loadVest GVAR(center) > 1} do { + GVAR(center) removeItemFromVest (_backpackItems select _index); + DEC(_index); + }; - if ((GVAR(currentItems) select 5) != _item) then { - GVAR(center) addVest _item; - while {count vestItems GVAR(center) > 0} do { - GVAR(center) removeItemFromVest (VestItems GVAR(center) select 0); - }; //--- Remove default config contents - {GVAR(center) addItemToVest _x} foreach (GVAR(currentItems) select 16); - - GVAR(currentItems) set [5, _item]; + GVAR(currentItems) set [IDX_CURR_VEST, _item]; }; TOGGLE_RIGHT_PANEL_CONTAINER + [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonBackpack : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Backpack + case IDC_buttonBackpack: { if (_item == "") then { - removeBackpack GVAR(center); - GVAR(currentItems) set [17, []]; - GVAR(currentItems) set [6, _item]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, []]; + GVAR(currentItems) set [IDX_CURR_BACKPACK, ""]; + TOGGLE_RIGHT_PANEL_HIDE } else { + if ((GVAR(currentItems) select IDX_CURR_BACKPACK) != _item) then { + // Get the unit's current loadout and just change the container + private _loadout = getUnitLoadout GVAR(center); + _loadout set [IDX_LOADOUT_BACKPACK, [_item, GVAR(currentItems) select IDX_CURR_BACKPACK_ITEMS]]; + GVAR(center) setUnitLoadout _loadout; + + private _backpackItems = backpackItems GVAR(center); + private _index = count _backpackItems - 1; + + // Remove any items that can't fit in the container (this prevents overloading) + while {loadBackpack GVAR(center) > 1} do { + GVAR(center) removeItemFromBackpack (_backpackItems select _index); + DEC(_index); + }; - if ((GVAR(currentItems) select 6) != _item) then { - removeBackpack GVAR(center); - GVAR(center) addBackpackGlobal _item; - while {count backpackItems GVAR(center) > 0} do { - GVAR(center) removeItemFromBackpack (backpackItems GVAR(center) select 0); - }; //--- Remove default config contents - {GVAR(center) addItemToBackpack _x} foreach (GVAR(currentItems) select 17); - - GVAR(currentItems) set [6, _item]; + GVAR(currentItems) set [IDX_CURR_BACKPACK, _item]; }; TOGGLE_RIGHT_PANEL_CONTAINER + [_display, _selectCorrectPanelContainer] call FUNC(fillRightPanel); }; + // Make unit switch to new item call FUNC(showItem); - [_display, _control, _curSel, (configFile >> "CfgVehicles" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonGoggles : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgVehicles" >> _item] call FUNC(itemInfo); + }; + // Facewear + case IDC_buttonGoggles: { if (_item == "") then { removeGoggles GVAR(center); - GVAR(currentItems) set [7, _item]; + GVAR(currentItems) set [IDX_CURR_GOGGLES, ""]; } else { - if ((GVAR(currentItems) select 7) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_GOGGLES) != _item) then { GVAR(center) addGoggles _item; - GVAR(currentItems) set [7, _item]; + GVAR(currentItems) set [IDX_CURR_GOGGLES, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgGlasses" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonNVG : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgGlasses" >> _item] call FUNC(itemInfo); + }; + // NVG + case IDC_buttonNVG: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 8); - GVAR(currentItems) set [8, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_NVG); + GVAR(currentItems) set [IDX_CURR_NVG, ""]; } else { - if ((GVAR(currentItems) select 8) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_NVG) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [8, _item]; + GVAR(currentItems) set [IDX_CURR_NVG, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); }; + // Binoculars + case IDC_buttonBinoculars: { + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_BINO) call EFUNC(common,baseWeapon); - case IDC_buttonBinoculars : { + // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { + call _fnc_clearPreviousWepMags; + GVAR(center) removeWeapon (binocular GVAR(center)); - GVAR(currentItems) set [9, _item]; + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, ["", "", "", "", "", ""]]; + GVAR(currentItems) set [IDX_CURR_BINO, ""]; + + TOGGLE_RIGHT_PANEL_HIDE } else { - if ((GVAR(currentItems) select 9) != _item) then { - GVAR(center) addWeapon _item; - GVAR(currentItems) set [9, _item]; - call FUNC(showItem); - ADDBINOCULARSMAG + // Check if a new binocular was selected + if ((GVAR(currentItems) select IDX_CURR_BINO) != _item && {_baseWeapon != _item}) then { + // Get magazines that are compatible with the new binocular + private _compatibleMags = compatibleMagazines _item; + private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + + // Remove all magazines from the previous binocular that aren't compatible with the new one + call _fnc_clearPreviousWepMags; + + // Add new weapon without taking a magazine from the inventory + [GVAR(center), _item] call EFUNC(common,addWeapon); + + private _linkedItems = binocularItems GVAR(center) - [""]; + + // Remove linked items if unavailable + if (_linkedItems isNotEqualTo []) then { + private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); + + { + if !(_x in _availableAttachments) then { + GVAR(center) removeBinocularItem _x; + }; + } forEach _linkedItems; + }; + + // Add old attachments and magazines back if they are compatible + { + if (_item canAdd _x) then { + GVAR(center) addWeaponItem [_item, _x, true]; + }; + } forEach (GVAR(currentItems) select IDX_CURR_BINO_ITEMS); + + // Add a magazine to the binocular itself if necessary + if ((binocularMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { + GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + }; + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_BINO, _item]; }; + + TOGGLE_RIGHT_PANEL_WEAPON + + [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); }; + + // Make unit switch to new item call FUNC(showItem); - TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonMap : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Map + case IDC_buttonMap: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 10) select 0; - GVAR(currentItems) set [10, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_MAP); + GVAR(currentItems) set [IDX_CURR_MAP, ""]; } else { - if ((GVAR(currentItems) select 10) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_MAP) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [10, _item]; + GVAR(currentItems) set [IDX_CURR_MAP, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonCompass : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Compass + case IDC_buttonCompass: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 11) select 0; - GVAR(currentItems) set [11, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_COMPASS); + GVAR(currentItems) set [IDX_CURR_COMPASS, ""]; } else { - if ((GVAR(currentItems) select 11) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_COMPASS) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [11, _item]; + GVAR(currentItems) set [IDX_CURR_COMPASS, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonRadio : { + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Radio + case IDC_buttonRadio: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 12) select 0; - GVAR(currentItems) set [12, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_RADIO); + GVAR(currentItems) set [IDX_CURR_RADIO, ""]; } else { - if ((GVAR(currentItems) select 12) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_RADIO) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [12, _item]; + GVAR(currentItems) set [IDX_CURR_RADIO, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonWatch : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Watch + case IDC_buttonWatch: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 13); - GVAR(currentItems) set [13, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_WATCH); + GVAR(currentItems) set [IDX_CURR_WATCH, ""]; } else { - if ((GVAR(currentItems) select 13) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_WATCH) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [13, _item]; + GVAR(currentItems) set [IDX_CURR_WATCH, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonGPS : { + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // GPS or UAV Terminal + case IDC_buttonGPS: { if (_item == "") then { - GVAR(center) unlinkItem (GVAR(currentItems) select 14) select 0; - GVAR(currentItems) set [14, _item]; + GVAR(center) unlinkItem (GVAR(currentItems) select IDX_CURR_COMMS); + GVAR(currentItems) set [IDX_CURR_COMMS, ""]; } else { - if ((GVAR(currentItems) select 14) != _item) then { + if ((GVAR(currentItems) select IDX_CURR_COMMS) != _item) then { GVAR(center) linkItem _item; - GVAR(currentItems) set [14, _item]; + GVAR(currentItems) set [IDX_CURR_COMMS, _item]; }; }; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgWeapons" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonFace : { + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; + // Face + case IDC_buttonFace: { private _face = [_item, "Default"] select (_item == ""); GVAR(center) setFace _face; GVAR(currentFace) = _face; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgFaces" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonVoice : { + [_display, _control, _curSel, configFile >> "CfgFaces" >> _item] call FUNC(itemInfo); + }; + // Voice + case IDC_buttonVoice: { GVAR(center) setSpeaker _item; GVAR(currentVoice) = _item; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - [_display, _control, _curSel, (configFile >> "CfgVoice" >> _item)] call FUNC(itemInfo); - }; - case IDC_buttonInsignia : { - [GVAR(center), _item] call bis_fnc_setUnitInsignia; + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgVoice" >> _item] call FUNC(itemInfo); + }; + // Insignia + case IDC_buttonInsignia: { + [GVAR(center), _item] call BIS_fnc_setUnitInsignia; GVAR(currentInsignia) = _item; + // Make unit switch to new item call FUNC(showItem); + TOGGLE_RIGHT_PANEL_HIDE - private _unitInsigniaConfig = (configFile >> "CfgUnitInsignia" >> _item); + private _unitInsigniaConfig = configFile >> "CfgUnitInsignia" >> _item; - if (configName _unitInsigniaConfig isEqualTo "") then { - [_display, _control, _curSel, (missionConfigFile >> "CfgUnitInsignia" >> _item)] call FUNC(itemInfo); + // Display new items's info on the bottom right + if (isNull _unitInsigniaConfig) then { + [_display, _control, _curSel, missionConfigFile >> "CfgUnitInsignia" >> _item] call FUNC(itemInfo); } else { [_display, _control, _curSel, _unitInsigniaConfig] call FUNC(itemInfo); }; }; }; -(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", GVAR(center) call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); diff --git a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf index 529f69da757..a9cdff05bb4 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf @@ -7,6 +7,7 @@ * Arguments: * 0: Loadouts panel control * 1: Loadouts panel selection + * 2: Currently selected loadout's index * * Return Value: * None @@ -23,74 +24,76 @@ private _deleteButtonCtrl = _display displayCtrl IDC_buttonDelete; private _renameButtonCtrl = _display displayCtrl IDC_buttonRename; private _textEditBoxCtrl= _display displayCtrl IDC_textEditBox; +// If nothing selected, disable all buttons if (_curSel == -1) exitWith { - if (GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts) then { _saveButtonCtrl ctrlEnable false; _saveButtonCtrl ctrlCommit 0; }; - _shareButtonCtrl ctrlSetText (localize LSTRING(buttonSharePrivateText)); + _shareButtonCtrl ctrlSetText LLSTRING(buttonSharePrivateText); { _x ctrlEnable false; _x ctrlCommit 0; - } foreach [_shareButtonCtrl, _loadButtonCtrl, _deleteButtonCtrl, _renameButtonCtrl]; + } forEach [_shareButtonCtrl, _loadButtonCtrl, _renameButtonCtrl, _deleteButtonCtrl]; }; switch (GVAR(currentLoadoutsTab)) do { - + // Local loadouts case IDC_buttonMyLoadouts: { - + // Enable shared loadouts if option is enabled and MP _shareButtonCtrl ctrlEnable (GVAR(allowSharedLoadouts) && {isMultiplayer}); _shareButtonCtrl ctrlCommit 0; - _loadButtonCtrl ctrlEnable true; - _loadButtonCtrl ctrlCommit 0; - - _shareButtonCtrl ctrlSetText ( [ - localize LSTRING(buttonSharePrivateText), - localize LSTRING(buttonSharePublicText) + // Rename share button, depending if it's already shared or not + _shareButtonCtrl ctrlSetText ([ + LLSTRING(buttonSharePrivateText), + LLSTRING(buttonSharePublicText) ] select ((_control lnbValue [_curSel, 0]) == 1)); + // Enable all other buttons { _x ctrlEnable true; _x ctrlCommit 0; - } foreach [_renameButtonCtrl, _deleteButtonCtrl]; + } forEach [_loadButtonCtrl, _renameButtonCtrl, _deleteButtonCtrl]; _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); }; - + // Default loadouts case IDC_buttonDefaultLoadouts: { - + // Enable saving and loading for everyone { _x ctrlEnable true; _x ctrlCommit 0; - } foreach [_saveButtonCtrl, _loadButtonCtrl]; + } forEach [_saveButtonCtrl, _loadButtonCtrl]; + // Disable sharing button _shareButtonCtrl ctrlEnable false; _shareButtonCtrl ctrlCommit 0; + // Enable delete and renaming button if in 3DEN { _x ctrlEnable (is3DEN); _x ctrlCommit 0; - } foreach [_deleteButtonCtrl, _renameButtonCtrl]; + } forEach [_renameButtonCtrl, _deleteButtonCtrl]; _textEditBoxCtrl ctrlSetText (_control lnbText [_curSel, 1]); }; - + // Shared loadouts case IDC_buttonSharedLoadouts: { - + // Enable saving and loading for everyone { _x ctrlEnable true; _x ctrlCommit 0; - } foreach [_saveButtonCtrl, _loadButtonCtrl]; + } forEach [_saveButtonCtrl, _loadButtonCtrl]; + // Disable sharing button _shareButtonCtrl ctrlEnable false; _shareButtonCtrl ctrlCommit 0; + // If admin or loadout author, enable button for shared loadout if ((serverCommandAvailable "#logout") || {(_control lnbText [_curSel, 0]) == profileName}) then { - _deleteButtonCtrl ctrlEnable true; _deleteButtonCtrl ctrlCommit 0; } else { diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index 7c1cb813e0e..4ddc5250ceb 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles selection changes on the right panel. * * Arguments: @@ -18,61 +18,79 @@ params ["_control", "_curSel"]; if (_curSel < 0) exitwith {}; -private _ctrlIDC = ctrlIDC _control; private _display = ctrlParent _control; private _item = _control lbData _curSel; +private _currentItemsIndex = 18 + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun, IDC_buttonBinoculars] find GVAR(currentLeftPanel)); +private _itemIndex = [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find GVAR(currentRightPanel); +// Check which right panel has changed +switch (_currentItemsIndex) do { + // Primary weapon + case IDX_CURR_PRIMARY_WEAPON_ITEMS: { + // If removal + if (_item == "") then { + GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex); + } else { + GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; + }; -private _fnc_selectItem = { - params ["_item", "_currentItemsIndex", "_itemIndex"]; + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_PRIMARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; - switch (_currentItemsIndex) do { - case 18: { - if (_item == "") then { - GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select 18) select _itemIndex); - private _primaryMags = primaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; - } else { - GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; - private _primaryMags = primaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [18, (primaryWeaponItems GVAR(center)) + ([_primaryMags + [""], _primaryMags] select (count _primaryMags > 1))]; + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); + }; + // Secondary weapon + case IDX_CURR_SECONDARY_WEAPON_ITEMS: { + if (_item == "") then { + if (CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}) exitWith { + TRACE_1("ignoring unload of disposable",secondaryWeapon GVAR(center)); }; - [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + + GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex); + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + } else { + GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; }; - case 19: { - if (_item == "") then { - if (cba_disposable_replaceDisposableLauncher && !isNil {cba_disposable_LoadedLaunchers getVariable secondaryWeapon GVAR(center)}) exitWith { TRACE_1("ignoring unload of disposable",secondaryWeapon GVAR(center)); }; - GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select 19) select _itemIndex); - private _secondaryMags = secondaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; - } else { - GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; - private _secondaryMags = secondaryWeaponMagazine GVAR(center); - GVAR(currentItems) set [19, (secondaryWeaponItems GVAR(center)) + ([_secondaryMags + [""], _secondaryMags] select (count _secondaryMags > 1))]; - }; - [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); + }; + // Handgun weapon + case IDX_CURR_HANDGUN_WEAPON_ITEMS: { + if (_item == "") then { + GVAR(center) removeHandgunItem ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex); + } else { + GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; }; - case 20: { - if (_item == "") then { - GVAR(center) removeHandgunItem ((GVAR(currentItems) select 20) select _itemIndex); - private _handgunMags = handgunMagazine GVAR(center); - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; - } else { - GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; - private _handgunMags = handgunMagazine GVAR(center); - GVAR(currentItems) set [20, (handgunItems GVAR(center)) + ([_handgunMags + [""], _handgunMags] select (count _handgunMags > 1))]; - }; - [_display, _control, _curSel, (configFile >> (["CfgWeapons", "CfgMagazines"] select (_itemIndex in [4, 5]))>> _item)] call FUNC(itemInfo); + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); + }; + // Binoculars + case IDX_CURR_BINO_ITEMS: { + if (_item == "") then { + GVAR(center) removeBinocularItem ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex); + } else { + GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; }; + + // Update currentItems + (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); }; }; -[ - _item, - 18 + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find GVAR(currentLeftPanel)), - [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find GVAR(currentRightPanel) -] call _fnc_selectItem; - -(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); +// Update weight display +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", GVAR(center) call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); diff --git a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf index 0c535c8d37a..638f2af2a30 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf @@ -1,12 +1,12 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles selection changes on the right panel (listnbox). * * Arguments: * 0: Right panel control - * 1: Right panel selection + * 1: Right panel selection * * Return Value: * None @@ -16,36 +16,34 @@ params ["_control", "_curSel"]; -if (_curSel < 0) exitwith {}; - -private _ctrlIDC = ctrlIDC _control; -private _display = ctrlParent _control; -private _item = [_control lnbData [_curSel, 0], _control lbData _curSel] select !(ctrlType _control == 102); - -private _fnc_selectRight = { - params ["_item", "_cfgEntry"]; - - // Load remaining - private _maxLoad = switch (GVAR(currentLeftPanel)) do { - case IDC_buttonUniform: { - gettext (configfile >> "CfgWeapons" >> uniform GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonVest: { - gettext (configfile >> "CfgWeapons" >> vest GVAR(center) >> "ItemInfo" >> "containerClass") - }; - case IDC_buttonBackpack: { - backpack GVAR(center) - }; +if (_curSel < 0 || {!(GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack])}) exitWith {}; + +private _hasItems = false; + +// Get relevant container +private _container = switch (GVAR(currentLeftPanel)) do { + case IDC_buttonUniform: { + _hasItems = (GVAR(currentItems) select IDX_CURR_UNIFORM_ITEMS) isNotEqualTo []; + + uniformContainer GVAR(center) + }; + case IDC_buttonVest: { + _hasItems = (GVAR(currentItems) select IDX_CURR_VEST_ITEMS) isNotEqualTo []; + + vestContainer GVAR(center) }; + case IDC_buttonBackpack: { + _hasItems = (GVAR(currentItems) select IDX_CURR_BACKPACK_ITEMS) isNotEqualTo []; - [_control, _maxLoad] call FUNC(updateRightPanel); - [_display, _control, _curSel, (configFile >> _cfgEntry >> _item)] call FUNC(itemInfo); + backpackContainer GVAR(center) + }; }; -if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { +// Refresh availibility of items based on space remaining in container +[_control, _container, _hasItems] call FUNC(updateRightPanel); - [ - _item, - ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut]) - ] call _fnc_selectRight; -}; +private _item = _control lnbData [_curSel, 0]; +private _cfgEntry = ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut]); + +// Display item info on the bottom right +[ctrlParent _control, _control, _curSel, configFile >> _cfgEntry >> _item] call FUNC(itemInfo); diff --git a/addons/arsenal/functions/fnc_open3DEN.sqf b/addons/arsenal/functions/fnc_open3DEN.sqf index 103ec870e1e..03ced7888d4 100644 --- a/addons/arsenal/functions/fnc_open3DEN.sqf +++ b/addons/arsenal/functions/fnc_open3DEN.sqf @@ -9,9 +9,8 @@ * Return Value: * None * - * * Public: No */ -private _entity = (uinamespace getvariable ["bis_fnc_3DENEntityMenu_data",[]]) param [1, objnull]; +private _entity = (uiNamespace getVariable ["BIS_fnc_3DENEntityMenu_data", []]) param [1, objNull]; [_entity, _entity, true] call FUNC(openBox); diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf index f1c6612671d..2c97f13b920 100644 --- a/addons/arsenal/functions/fnc_openBox.sqf +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -1,6 +1,7 @@ #include "script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Open arsenal. * * Arguments: @@ -26,30 +27,34 @@ if ( {!(isNull objectParent _center) && {!is3DEN}} ) exitWith {}; -if (isNil {_object getVariable [QGVAR(virtualItems), nil]} && {!_mode}) exitWith { - [localize LSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); +// If object has no arsenal and chosen option is to not ignore virtual items of object, exit +if (isNil {_object getVariable QGVAR(virtualItems)} && {!_mode}) exitWith { + [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); }; +// Don't execute in scheduled environment if (canSuspend) exitWith { [{_this call FUNC(openBox)}, _this] call CBA_fnc_directCall; }; -private _displayToUse = [findDisplay 46, findDIsplay 312] select (!isNull findDisplay 312); -_displayToUse = [_displayToUse, findDisplay 313] select (is3DEN); +private _displayToUse = findDisplay IDD_RSCDISPLAYCURATOR; +_displayToUse = [_displayToUse, findDisplay IDD_MISSION] select (isNull _displayToUse); +_displayToUse = [_displayToUse, findDisplay IDD_DISPLAY3DEN] select is3DEN; -if (isNil "_displayToUse" || {!isnil QGVAR(camera)}) exitWith { - [localize LSTRING(CantOpenDisplay), false, 5, 1] call EFUNC(common,displayText); +// Check if the display is available and that there isn't already a camera for the arsenal +if (isNull _displayToUse || {!isNil QGVAR(camera)}) exitWith { + [LLSTRING(CantOpenDisplay), false, 5, 1] call EFUNC(common,displayText); }; GVAR(currentBox) = _object; if (_mode) then { + // Add all the items from the game that the arsenal has detected GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); GVAR(virtualItemsFlat) = +(uiNamespace getVariable QGVAR(configItemsFlat)); } else { - GVAR(virtualItems) = +(_object getVariable [QGVAR(virtualItems), [ - [[], [], []], [[], [], [], []], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [] - ]]); + // Add only specified items to the arsenal + GVAR(virtualItems) = +(_object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]); GVAR(virtualItemsFlat) = flatten GVAR(virtualItems); }; @@ -58,5 +63,7 @@ GVAR(center) = _center; if (is3DEN) then { _displayToUse createDisplay QGVAR(display); } else { - [{(_this select 0) createDisplay (_this select 1)}, [_displayToUse, QGVAR(display)]] call CBA_fnc_execNextFrame; + [{ + _this createDisplay QGVAR(display); + }, _displayToUse] call CBA_fnc_execNextFrame; }; diff --git a/addons/arsenal/functions/fnc_portVALoadouts.sqf b/addons/arsenal/functions/fnc_portVALoadouts.sqf index 0e403eae92f..2fc7c351b6a 100644 --- a/addons/arsenal/functions/fnc_portVALoadouts.sqf +++ b/addons/arsenal/functions/fnc_portVALoadouts.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: alganthe + * Author: Alganthe, johnb43 * Port VA loadouts to ACE Arsenal. * * Arguments: @@ -12,31 +12,40 @@ * Public: Yes */ -private _VALoadouts = +(profilenamespace getvariable ["bis_fnc_saveInventory_data",[]]); -private _aceLoadouts = +(profileNamespace getVariable [QGVAR(saved_loadouts),[]]); +private _unit = player; -if (isNull player) exitWith { - [localize LSTRING(portLoadoutsPlayerError)] call BIS_fnc_error; +// Need a player object to transfer loadouts +if (isNull _unit) exitWith { + [LLSTRING(portLoadoutsPlayerError)] call BIS_fnc_error; }; +// Check if there are any VA loadouts +private _VALoadouts = profileNamespace getVariable ["BIS_fnc_saveInventory_data", []]; + if (_VALoadouts isEqualTo []) exitWith { - [localize LSTRING(portLoadoutsLoadoutError)] call BIS_fnc_error; + [LLSTRING(portLoadoutsLoadoutError)] call BIS_fnc_error; }; -for "_i" from 0 to (count _VALoadouts - 1) step 2 do { - _name = _VALoadouts select _i; - _inventory = _VALoadouts select (_i + 1); +private _aceLoadouts = +(profileNamespace getVariable [QGVAR(saved_loadouts),[]]); +private _name = ""; +private _index = -1; - private _sameNameLoadoutsList = _aceLoadouts select {_x select 0 == _name}; - [player, [profilenamespace, _name]] call bis_fnc_loadinventory; +// Go through all VA loadouts and save them as ACE Arsenal loadouts +for "_i" from 0 to (count _VALoadouts) - 1 step 2 do { + _name = _VALoadouts select _i; - private _loadout = getUnitLoadout player; + // Load VA loadout onto player + [_unit, [profileNamespace, _name]] call BIS_fnc_loadInventory; - if (count _sameNameLoadoutsList > 0) then { - _aceLoadouts set [_aceLoadouts find (_sameNameLoadoutsList select 0), [_name, _loadout]]; + // See if there is an already existing loadout with the same name + _index = _aceLoadouts findIf {(_x select 0) == _name}; + // If there is an already existing loadout with same name, overwrite it (in CBA extended loadout array) + if (_index != -1) then { + _aceLoadouts set [_index, [_name, [getUnitLoadout _unit, createHashMap]]]; } else { - _aceLoadouts pushBack [_name, _loadout]; + // Otherwise just add + _aceLoadouts pushBack [_name, [getUnitLoadout _unit, createHashMap]]; }; }; diff --git a/addons/arsenal/functions/fnc_removeBox.sqf b/addons/arsenal/functions/fnc_removeBox.sqf index 7620529ef3e..8e3c8a73753 100644 --- a/addons/arsenal/functions/fnc_removeBox.sqf +++ b/addons/arsenal/functions/fnc_removeBox.sqf @@ -1,11 +1,11 @@ #include "script_component.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Remove arsenal from target. * * Arguments: * 0: Target - * 1: Remove globally + * 1: Remove globally (Optional) * * Return Value: * None @@ -18,18 +18,23 @@ params [["_object", objNull, [objNull]], ["_global", true, [true]]]; -if (isNull _object || {isNil QGVAR(EHIDArray)}) exitWith {}; +if (isNull _object) exitWith {}; -if (_global && {isMultiplayer}) then { - private _ID = (GVAR(EHIDArray) select {_x select 1 == _object}) select 0; +private _id = _object getVariable QGVAR(initBoxJIP); - if (!isNil "_ID") then { - [_ID select 0] call CBA_fnc_removeGlobalEventJIP; - GVAR(EHIDArray) deleteAt (GVAR(EHIDArray) find _ID); - publicVariable QGVAR(EHIDArray); - [QGVAR(removeBox), [_object, false]] call CBA_fnc_globalEvent; - }; +if (_global && {isMultiplayer} && {!isNil "_id"}) then { + // Remove event from JIP queue + [_id] call CBA_fnc_removeGlobalEventJIP; + + // Reset JIP ID + _object setVariable [QGVAR(initBoxJIP), nil, true]; + + // Remove box for everyone + [QGVAR(removeBox), [_object, false]] call CBA_fnc_globalEvent; + + // Remove from JIP + _object setVariable [QGVAR(virtualItems), nil, true]; } else { - _object setVariable [QGVAR(virtualItems), nil, false]; + _object setVariable [QGVAR(virtualItems), nil]; [_object, 0, ["ACE_MainActions", QGVAR(interaction)]] call EFUNC(interact_menu,removeActionFromObject); }; diff --git a/addons/arsenal/functions/fnc_removeStat.sqf b/addons/arsenal/functions/fnc_removeStat.sqf index 79f21737984..b6fd0273ac7 100644 --- a/addons/arsenal/functions/fnc_removeStat.sqf +++ b/addons/arsenal/functions/fnc_removeStat.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [["scopeStatL00","scopeStatL01","scopeStatL02","scopeStatR07"]] call ace_arsenal_fnc_removeStat; + * [["scopeStatL00", "scopeStatL01", "scopeStatL02", "scopeStatR07"]] call ace_arsenal_fnc_removeStat; * * Public: Yes */ @@ -24,6 +24,7 @@ call FUNC(compileStats); 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 { @@ -34,24 +35,26 @@ call FUNC(compileStats); { _x deleteAt (_x findIf {_x select 0 == _currentID}); - } foreach _tabToChange; -} foreach _IDList; + } forEach _tabToChange; +} forEach _IDList; // Clear empty pages private _fnc_deleteEmptyPage = { params ["_list"]; + { private _evaluatedTab = _forEachIndex; + { if (count _x == 0) then { _markedForDeletion pushBack [_evaluatedTab, _forEachIndex]; }; - } foreach _x; + } forEach _x; { (_list select (_x select 0)) deleteAt (_x select 1); - } foreach _markedForDeletion; - } foreach (_this select 0); + } forEach _markedForDeletion; + } forEach (_this select 0); }; private _markedForDeletion = []; diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf index ad9ff7f89eb..706d483b89b 100644 --- a/addons/arsenal/functions/fnc_removeVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -1,12 +1,13 @@ #include "script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Remove virtual items to the provided target. * * Arguments: * 0: Target - * 1: Items - * 2: Add globally + * 1: Items , + * 2: Add globally (Optional) * * Return Value: * None @@ -18,63 +19,64 @@ * Public: Yes */ -params [ ["_object", objNull, [objNull]], ["_items", [], [true, [""]]], ["_global", false, [false]] ]; +params [["_object", objNull, [objNull]], ["_items", [], [true, [""]]], ["_global", false, [false]]]; -if (_object == objNull) exitWith {}; -if (_items isEqualType [] && {count _items == 0}) exitWith {}; - -private _cargo = _object getVariable [QGVAR(virtualItems), [ - [[], [], []], // Weapons 0, primary, handgun, secondary - [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod - [ ], // Magazines 2 - [ ], // Headgear 3 - [ ], // Uniform 4 - [ ], // Vest 5 - [ ], // Backpacks 6 - [ ], // Goggles 7 - [ ], // NVGs 8 - [ ], // Binoculars 9 - [ ], // Map 10 - [ ], // Compass 11 - [ ], // Radio slot 12 - [ ], // Watch slot 13 - [ ], // Comms slot 14 - [ ], // WeaponThrow 15 - [ ], // WeaponPut 16 - [ ] // InventoryItems 17 -]]; +if (isNull _object || {_items isEqualTo []}) exitWith {}; if (_items isEqualType true) then { if (_items) then { [_object, _global] call FUNC(removeBox); - _object setVariable [QGVAR(virtualItems), nil, _global]; }; } else { + // Make sure all items are in string form, then convert to config case (non-existent items return "") + _items = (_items select {_x isEqualType ""}) apply {_x call EFUNC(common,getConfigName)}; + + // Remove any invalid/non-existing items + _items = _items - [""]; - // Make sure all items are in string form - _items = _items select {_x isEqualType "" && {_x != ""}}; + private _cargo = _object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]; + private _isEmpty = true; + private _newItems = []; + // Remove items from lists { - if (_forEachIndex isEqualTo 0) then { - _cargo set [_forEachIndex, [(_x select 0) - _items, (_x select 1) - _items, (_x select 2) - _items]]; - } else { - if (_forEachIndex isEqualTo 1) then { - _cargo set [_forEachIndex, [(_x select 0) - _items, (_x select 1) - _items, (_x select 2) - _items, (_x select 3) - _items]]; - } else { - _cargo set [_cargo find _x, _x - _items]; + switch (_forEachIndex) do { + // Weapons + case IDX_VIRT_WEAPONS: { + _cargo set [_forEachIndex, [ + (_x select IDX_VIRT_PRIMARY_WEAPONS) - _items, + (_x select IDX_VIRT_SECONDARY_WEAPONS) - _items, + (_x select IDX_VIRT_HANDGUN_WEAPONS) - _items + ]]; + + // Check that there are still items left in the arsenal + _isEmpty = (_cargo select _forEachIndex) isEqualTo [[], [], []]; }; - }; - } foreach _cargo; + // Weapon attachments + case IDX_VIRT_ATTACHMENTS: { + _cargo set [_forEachIndex, [ + (_x select IDX_VIRT_OPTICS_ATTACHMENTS) - _items, + (_x select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) - _items, + (_x select IDX_VIRT_MUZZLE_ATTACHMENTS) - _items, + (_x select IDX_VIRT_BIPOD_ATTACHMENTS) - _items + ]]; + + // Check that there are still items left in the arsenal + _isEmpty = _isEmpty && {(_cargo select _forEachIndex) isEqualTo [[], [], [], []]}; + }; + // Rest + default { + _newItems = _x - _items; + _cargo set [_forEachIndex, _newItems]; - private _itemCount = { - if (_x isEqualTo (_cargo select 0) || {_x isEqualTo (_cargo select 1)}) then { - (_x isNotEqualTo [[],[],[]] || {_x isEqualTo [[],[],[],[]]}) - } else { - (_x isNotEqualTo []) + // Check that there are still items left in the arsenal + _isEmpty = _isEmpty && {_newItems isEqualTo []}; + }; }; - } count _cargo; + } forEach _cargo; - if (_itemCount == 0) then { + // If nothing is left, remove arsenal from object + if (_isEmpty) then { [_object, _global] call FUNC(removeBox); } else { _object setVariable [QGVAR(virtualItems), _cargo, _global]; diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf new file mode 100644 index 00000000000..50a06997546 --- /dev/null +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -0,0 +1,112 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43 + * Replaces unique items in a loadout with their base items. Weapons are replaced with their base weapon. + * + * Arguments: + * 0: CBA extended loadout or getUnitLoadout array + * + * Return Value: + * Sanitised loadout (getUnitLoadout array) + * + * Example: + * [getUnitLoadout player] call ace_arsenal_fnc_replaceUniqueItemsLoadout + * + * Public: Yes +*/ + +params [["_loadout", [], [[]]]]; + +// IF CBA extended loadout, just take getUnitLoadout array +if (count _loadout == 2) then { + _loadout = _loadout select 0; +}; + +if (count _loadout != 10) exitWith {[]}; + +private _weapon = ""; +private _uniqueBaseCfgText = ""; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; + +{ + switch (_forEachIndex) do { + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + _x params [["_weapon", ""]]; + + // Find baseweapon of weapon + if (_weapon != "") then { + _x set [0, _weapon call EFUNC(common,baseWeapon)]; + }; + }; + // Uniform, vest, backpack + case IDX_LOADOUT_UNIFORM; + case IDX_LOADOUT_VEST; + case IDX_LOADOUT_BACKPACK: { + _x params ["", ["_items", []]]; + + // Check if container has items that need replacing with a defined base + { + switch (true) do { + // Containers have 2 entries: Name and isBackpack + case (_x isEqualTypeArray ["", false]); + // Misc. items have 2 entries: Name and amount + case (_x isEqualTypeArray ["", 0]): { + _x params ["_item", "_arg"]; + + if (_item != "") then { + _uniqueBaseCfgText = getText ([_cfgVehicles, _cfgWeapons] select (_arg isEqualType 0) >> _item >> QGVAR(uniqueBase)); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + }; + // Weapons have 2 entries: Weapon info array and amount + case (_x isEqualTypeArray [[], 0]): { + _weapon = (_x select 0) select 0; + + if (_weapon != "") then { + (_x select 0) set [0, _weapon call EFUNC(common,baseWeapon)]; + }; + }; + // Magazines have 3 entries: Name, amount and ammo count + case (_x isEqualTypeArray ["", 0, 0]): { + _x params ["_item"]; + + if (_item != "") then { + _uniqueBaseCfgText = getText (_cfgMagazines >> _item >> QGVAR(uniqueBase)); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + }; + }; + } forEach _items; + }; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + // Check if assignedItems have items that need replacing with a defined base + _items = _x; + + { + if (_x != "") then { + _uniqueBaseCfgText = getText (_cfgWeapons >> _x >> QGVAR(uniqueBase)); + + if (_uniqueBaseCfgText != "") then { + _items set [_forEachIndex, _uniqueBaseCfgText]; + }; + }; + } forEach _items; + }; + }; +} forEach _loadout; + +_loadout diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 26660d048c1..44884dbb247 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -1,7 +1,8 @@ #include "script_component.hpp" +#include "..\defines.hpp" /* - * Author: Dedmen - * Cache an array of all the compatible items for arsenal. + * Author: Dedmen, johnb43 + * Cache an array of all the compatible items for arsenals. * * Arguments: * None @@ -12,178 +13,223 @@ * Public: No */ -private _cargo = [ - [[], [], []], // Weapons 0, primary, secondary, handgun - [[], [], [], []], // WeaponAccessories 1, optic,side,muzzle,bipod - [ ], // Magazines 2 - [ ], // Headgear 3 - [ ], // Uniform 4 - [ ], // Vest 5 - [ ], // Backpacks 6 - [ ], // Goggles 7 - [ ], // NVGs 8 - [ ], // Binoculars 9 - [ ], // Map 10 - [ ], // Compass 11 - [ ], // Radio slot 12 - [ ], // Watch slot 13 - [ ], // Comms slot 14 - [ ], // WeaponThrow 15 - [ ], // WeaponPut 16 - [ ] // InventoryItems 17 -]; - -private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in variable for perf improvement +private _configItems = EMPTY_VIRTUAL_ARSENAL; +private _filterFunction = [{ + isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1} +}] call EFUNC(common,codeToString); + +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _className = ""; +private _configItemInfo = ""; +private _simulationType = ""; +private _hasItemInfo = false; +private _itemInfoType = 0; +private _isMiscItem = false; + +// Get weapons and other various items { - private _configItemInfo = _x >> "ItemInfo"; - private _simulationType = getText (_x >> "simulation"); - private _className = configName _x; - private _hasItemInfo = isClass (_configItemInfo); - private _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; - private _isMiscItem = _className isKindOf ["CBA_MiscItem", (_configCfgWeapons)]; - - switch true do { - /* Weapon acc */ + _className = configName _x; + _simulationType = getText (_x >> "simulation"); + _configItemInfo = _x >> "ItemInfo"; + _hasItemInfo = isClass (_configItemInfo); + _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; + _isMiscItem = _className isKindOf ["CBA_MiscItem", _cfgWeapons]; + + switch (true) do { + // Weapon attachments case ( - _hasItemInfo && - {_itemInfoType in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} && - {!_isMiscItem} - ): { - - //Convert type to array index - (_cargo select 1) select ([TYPE_OPTICS,TYPE_FLASHLIGHT,TYPE_MUZZLE,TYPE_BIPOD] find _itemInfoType) pushBackUnique _className; - }; - /* Headgear */ + _hasItemInfo && + {!_isMiscItem} && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]} + ): { + // Convert type to array index + ((_configItems select IDX_VIRT_ATTACHMENTS) select ([TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] find _itemInfoType)) pushBackUnique _className; + }; + // Headgear case (_itemInfoType == TYPE_HEADGEAR): { - (_cargo select 3) pushBackUnique _className; + (_configItems select IDX_VIRT_HEADGEAR) pushBackUnique _className; }; - /* Uniform */ + // Uniform case (_itemInfoType == TYPE_UNIFORM): { - (_cargo select 4) pushBackUnique _className; + (_configItems select IDX_VIRT_UNIFORM) pushBackUnique _className; }; - /* Vest */ + // Vest case (_itemInfoType == TYPE_VEST): { - (_cargo select 5) pushBackUnique _className; + (_configItems select IDX_VIRT_VEST) pushBackUnique _className; }; - /* NVgs */ + // NVgs case (_simulationType == "NVGoggles"): { - (_cargo select 8) pushBackUnique _className; + (_configItems select IDX_VIRT_NVG) pushBackUnique _className; }; - /* Binos */ - case (_simulationType == "Binocular" || - ((_simulationType == 'Weapon') && {(getNumber (_x >> 'type') == TYPE_BINOCULAR_AND_NVG)})): { - (_cargo select 9) pushBackUnique _className; + // Binos + case ( + _simulationType == "Binocular" || + {_simulationType == "Weapon" && {getNumber (_x >> "type") == TYPE_BINOCULAR_AND_NVG}} + ): { + (_configItems select IDX_VIRT_BINO) pushBackUnique _className; }; - /* Map */ + // Map case (_simulationType == "ItemMap"): { - (_cargo select 10) pushBackUnique _className; + (_configItems select IDX_VIRT_MAP) pushBackUnique _className; }; - /* Compass */ + // Compass case (_simulationType == "ItemCompass"): { - (_cargo select 11) pushBackUnique _className; + (_configItems select IDX_VIRT_COMPASS) pushBackUnique _className; }; - /* Radio */ + // Radio// case (_simulationType == "ItemRadio"): { - (_cargo select 12) pushBackUnique _className; + (_configItems select IDX_VIRT_RADIO) pushBackUnique _className; }; - /* Watch */ + // Watch case (_simulationType == "ItemWatch"): { - (_cargo select 13) pushBackUnique _className; + (_configItems select IDX_VIRT_WATCH) pushBackUnique _className; }; - /* GPS */ - case (_simulationType == "ItemGPS"): { - (_cargo select 14) pushBackUnique _className; - }; - /* UAV terminals */ - case (_itemInfoType == TYPE_UAV_TERMINAL): { - (_cargo select 14) pushBackUnique _className; + // GPS and UAV terminals + case ( + _simulationType == "ItemGPS" || + {_itemInfoType == TYPE_UAV_TERMINAL} + ): { + (_configItems select IDX_VIRT_COMMS) pushBackUnique _className; }; - /* Weapon, at the bottom to avoid adding binos */ - case (isClass (_x >> "WeaponSlotsInfo") && - {getNumber (_x >> 'type') != TYPE_BINOCULAR_AND_NVG}): { + // Weapon, at the bottom to avoid adding binos + case ( + isClass (_x >> "WeaponSlotsInfo") && + {getNumber (_x >> "type") != TYPE_BINOCULAR_AND_NVG} + ): { switch (getNumber (_x >> "type")) do { case TYPE_WEAPON_PRIMARY: { - (_cargo select 0) select 0 pushBackUnique (_className call bis_fnc_baseWeapon); + ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); }; case TYPE_WEAPON_HANDGUN: { - (_cargo select 0) select 2 pushBackUnique (_className call bis_fnc_baseWeapon); + ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); }; case TYPE_WEAPON_SECONDARY: { - (_cargo select 0) select 1 pushBackUnique (_className call bis_fnc_baseWeapon); + ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); }; }; }; - /* Misc items */ + // Misc items case ( - _hasItemInfo && - (_itemInfoType in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && - {_isMiscItem}) || - {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {(getText ( _x >> "simulation")) == "ItemMineDetector"} - ): { - (_cargo select 17) pushBackUnique _className; + _hasItemInfo && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] && + {_isMiscItem}} || + {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {getText (_x >> "simulation") == "ItemMineDetector"} + ): { + (_configItems select IDX_VIRT_MISC_ITEMS) pushBackUnique _className; }; }; -} foreach configProperties [_configCfgWeapons, "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; +} forEach configProperties [_cfgWeapons, _filterFunction, true]; +// Get all grenades private _grenadeList = []; + { - _grenadeList append getArray (_configCfgWeapons >> "Throw" >> _x >> "magazines"); -} foreach getArray (_configCfgWeapons >> "Throw" >> "muzzles"); + _grenadeList append getArray (_cfgWeapons >> "Throw" >> _x >> "magazines"); +} forEach getArray (_cfgWeapons >> "Throw" >> "muzzles"); +// Get all explosives, mines, IEDS and similar private _putList = []; + { - _putList append getArray (_configCfgWeapons >> "Put" >> _x >> "magazines"); -} foreach getArray (_configCfgWeapons >> "Put" >> "muzzles"); + _putList append getArray (_cfgWeapons >> "Put" >> _x >> "magazines"); +} forEach getArray (_cfgWeapons >> "Put" >> "muzzles"); + +// Convert both lists to config case +_grenadeList = _grenadeList apply {_x call EFUNC(common,getConfigName)}; +_putList = _putList apply {_x call EFUNC(common,getConfigName)}; + +// Remove invalid/non-existent entries +_grenadeList = _grenadeList - [""]; +_putList = _putList - [""]; +// Get all other grenades, explosives (and similar) and magazines { - private _className = configName _x; + _className = configName _x; - switch true do { + switch (true) do { // Grenades case (_className in _grenadeList): { - (_cargo select 15) pushBackUnique _className; + (_configItems select IDX_VIRT_GRENADES) pushBackUnique _className; }; - // Put + // Explosives case (_className in _putList): { - (_cargo select 16) pushBackUnique _className; + (_configItems select IDX_VIRT_EXPLOSIVES) pushBackUnique _className; }; - // Rifle, handgun, secondary weapons mags + // Primary, handgun & secondary weapon magazines, and magazines that are forced with "ace_arsenal_hide = -1" case ( - ((getNumber (_x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW,TYPE_MAGAZINE_SECONDARY_AND_PUT,1536,TYPE_MAGAZINE_HANDGUN_AND_GL,TYPE_MAGAZINE_MISSILE]) || - {(getNumber (_x >> QGVAR(hide))) == -1}) - ): { - (_cargo select 2) pushBackUnique _className; + getNumber (_x >> QGVAR(hide)) == -1 || + {getNumber (_x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL, TYPE_MAGAZINE_MISSILE]} + ): { + (_configItems select IDX_VIRT_ITEMS_ALL) pushBackUnique _className; }; }; -} foreach configProperties [(configFile >> "CfgMagazines"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; +} forEach configProperties [_cfgMagazines, _filterFunction, true]; +// Get all backpacks { if (getNumber (_x >> "isBackpack") == 1) then { - (_cargo select 6) pushBackUnique (configName _x); + (_configItems select IDX_VIRT_BACKPACK) pushBackUnique (configName _x); }; -} foreach configProperties [(configFile >> "CfgVehicles"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; +} forEach configProperties [configFile >> "CfgVehicles", _filterFunction, true]; +// Get all facewear { - (_cargo select 7) pushBackUnique (configName _x); -} foreach configProperties [(configFile >> "CfgGlasses"), "isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1}", true]; + (_configItems select IDX_VIRT_GOGGLES) pushBackUnique (configName _x); +} forEach configProperties [configFile >> "CfgGlasses", _filterFunction, true]; +// Get magazine groups (magazinewells) private _magazineGroups = createHashMap; +private _magazinesList = []; -private _cfgMagazines = configFile >> "CfgMagazines"; +{ + _magazinesList = []; + + { + // Filter out non-existent magazines, then make names config case + /////////////////////////////////////////////////////////////////// No filtering for scope ? + _magazinesList append (((getArray _x) select {isClass (_cfgMagazines >> _x)}) apply {configName (_cfgMagazines >> _x)}); + } forEach configProperties [_x, "isArray _x", true]; + + _magazineGroups set [toLower configName _x, _magazinesList arrayIntersect _magazinesList]; +} forEach configProperties [configFile >> "CfgMagazineWells", "isClass _x", true]; + +// Get all faces +private _faceCache = createHashMap; + +private _dlcName = ""; +private _modPicture = ""; { - private _magList = []; { - private _magazines = (getArray _x) select {isClass (_cfgMagazines >> _x)}; //filter out non-existent magazines - _magazines = _magazines apply {configName (_cfgMagazines >> _x)}; //Make sure classname case is correct - _magList append _magazines; - } foreach configProperties [_x, "isArray _x", true]; + if (getNumber (_x >> "disabled") == 0 && {getText (_x >> "head") != ""} && {configName _x != "Default"}) then { + _dlcName = _x call EFUNC(common,getAddon); + + _modPicture = ""; + + if (_dlcName != "") then { + _modPicture = (modParams [_dlcName, ["logo"]]) param [0, ""]; + }; + + _faceCache set [configName _x, [getText (_x >> "displayName"), _modPicture]]; + }; + } forEach ("true" configClasses _x); +} forEach ("true" configClasses (configfile >> "CfgFaces")); + +// Get all voices +private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [configfile >> "CfgVoice" >> "NoVoice"]; - _magazineGroups set [toLower configName _x, _magList arrayIntersect _magList]; -} foreach configProperties [(configFile >> "CfgMagazineWells"), "isClass _x", true]; +// Get all insignia +private _insigniaCache = "true" configClasses (configFile >> "CfgUnitInsignia"); -uiNamespace setVariable [QGVAR(configItems), _cargo]; -uiNamespace setVariable [QGVAR(configItemsFlat), flatten _cargo]; +// This contains config case entries only +uiNamespace setVariable [QGVAR(configItems), _configItems]; +uiNamespace setVariable [QGVAR(configItemsFlat), flatten _configItems]; uiNamespace setVariable [QGVAR(magazineGroups), _magazineGroups]; +uiNamespace setVariable [QGVAR(faceCache), _faceCache]; +uiNamespace setVariable [QGVAR(voiceCache), _voiceCache]; +uiNamespace setVariable [QGVAR(insigniaCache), _insigniaCache]; +uiNamespace setVariable [QGVAR(grenadeCache), _grenadeList]; +uiNamespace setVariable [QGVAR(putCache), _putList]; diff --git a/addons/arsenal/functions/fnc_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index 58142d5a3ff..1bbf32ca0b7 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -15,54 +15,46 @@ if (GVAR(centerNotPlayer)) exitWith {}; +// Determine action to play based on current category selection private _nextAction = switch (GVAR(currentLeftPanel)) do { - - case IDC_buttonPrimaryWeapon : { - ["Civil", "PrimaryWeapon"] select ((GVAR(currentItems) select 0) != "") - }; - case IDC_buttonSecondaryWeapon : { - ["Civil", "SecondaryWeapon"] select (GVAR(currentItems) select 1 != "") + // Primary weapon + case IDC_buttonPrimaryWeapon: { + ["Civil", "PrimaryWeapon"] select ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) != "") }; - case IDC_buttonHandgun : { - ["Civil", "HandGunOn"] select (GVAR(currentItems) select 2 != "") + // Secondary weapon + case IDC_buttonSecondaryWeapon: { + ["Civil", "SecondaryWeapon"] select ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) != "") }; - case IDC_buttonHeadgear; - case IDC_buttonUniform; - case IDC_buttonVest; - case IDC_buttonBackpack; - case IDC_buttonGoggles; - case IDC_buttonMap; - case IDC_buttonGPS; - case IDC_buttonRadio; - case IDC_buttonCompass; - case IDC_buttonWatch; - case IDC_buttonFace; - case IDC_buttonNVG : { - "Civil" + // Handgun weapon + case IDC_buttonHandgun: { + ["Civil", "HandGunOn"] select ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) != "") }; - case IDC_buttonBinoculars : { - ["Civil", "Binoculars"] select (GVAR(currentItems) select 9 != "") + // Binoculars + case IDC_buttonBinoculars: { + ["Civil", "Binoculars"] select ((GVAR(currentItems) select IDX_CURR_BINO) != "") }; - case IDC_buttonInsignia : { + // Insignia + case IDC_buttonInsignia: { "Salute" }; - case IDC_buttonVoice : { + // Voice + case IDC_buttonVoice: { GVAR(center) directSay "CuratorObjectPlaced"; "Civil" }; + // Other + default { + "Civil" + }; }; +// Play the action if a new category of item was selected if (_nextAction != GVAR(currentAction)) then { - switch (_nextAction) do { - case "PrimaryWeapon": { - GVAR(selectedWeaponType) = 0; - }; - case "SecondaryWeapon": { - GVAR(selectedWeaponType) = 1; - }; - case "HandGunOn": { - GVAR(selectedWeaponType) = 2; - }; + GVAR(selectedWeaponType) = switch (_nextAction) do { + case "PrimaryWeapon": {0}; + case "SecondaryWeapon": {1}; + case "HandGunOn": {2}; + default {GVAR(selectedWeaponType)}; }; if (simulationEnabled GVAR(center)) then { diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index d5524c90786..dc6d0536870 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -17,7 +17,7 @@ params ["_sortControl"]; private _display = ctrlParent _sortControl; -private _rightSort = ctrlIDC _sortControl == 17; +private _rightSort = ctrlIDC _sortControl == IDC_sortRightTab; private _right = _rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}; if (_rightSort) then { @@ -33,8 +33,8 @@ if (_rightSort) then { case IDC_buttonThrow; case IDC_buttonPut; case IDC_buttonMag; - case IDC_buttonMagALL: { configFile >> "CfgMagazines" }; - default { configFile >> "CfgWeapons" }; + case IDC_buttonMagALL: {configFile >> "CfgMagazines"}; + default {configFile >> "CfgWeapons"}; }, GVAR(sortListRightPanel) select ( switch (GVAR(currentRightPanel)) do { @@ -56,12 +56,12 @@ if (_rightSort) then { [ _display displayCtrl IDC_leftTabContent, switch (GVAR(currentLeftPanel)) do { - case IDC_buttonBackpack: { configFile >> "CfgVehicles" }; - case IDC_buttonGoggles: { configFile >> "CfgGlasses" }; - case IDC_buttonFace: { configFile >> "CfgFaces" >> "Man_A3" }; - case IDC_buttonVoice: { configFile >> "CfgVoice" }; - case IDC_buttonInsignia: { configFile >> "CfgUnitInsignia" }; - default { configFile >> "CfgWeapons" }; + case IDC_buttonBackpack: {configFile >> "CfgVehicles"}; + case IDC_buttonGoggles: {configFile >> "CfgGlasses"}; + case IDC_buttonFace: {configFile >> "CfgFaces" >> "Man_A3"}; + case IDC_buttonVoice: {configFile >> "CfgVoice"}; + case IDC_buttonInsignia: {configFile >> "CfgUnitInsignia"}; + default {configFile >> "CfgWeapons"}; }, (GVAR(sortListLeftPanel) select ([ IDC_buttonPrimaryWeapon, @@ -86,70 +86,89 @@ if (_rightSort) then { ] } params ["_panel", "_cfgClass", "_sorts"]; +// Get currently selected item private _curSel = if (_right) then { lnbCurSelRow _panel } else { lbCurSel _panel }; + private _selected = if (_right) then { - _panel lnbData [_curSel, 0]; + _panel lnbData [_curSel, 0] } else { _panel lbData _curSel }; +// Get sort's information private _sortName = _sortControl lbData (0 max lbCurSel _sortControl); private _sortConfig = _sorts select (0 max (_sorts findIf {(_x select 0) isEqualTo _sortName})); private _statement = _sortConfig select 2; +_sortConfig params ["", "", "_statement"]; +// Update last sort missionNamespace setVariable [ [QGVAR(lastSortLeft), QGVAR(lastSortRight)] select _rightSort, _sortConfig select 1 ]; private _originalNames = createHashMap; +private _item = ""; +private _quantity = ""; +private _itemCfg = configNull; +private _value = ""; +private _name = ""; +private _data = ""; private _for = if (_right) then { - for '_i' from 0 to ((lnbSize _panel select 0) - 1) + for '_i' from 0 to (lnbSize _panel select 0) - 1 } else { - for '_i' from 0 to (lbSize _panel - 1) + for '_i' from 0 to (lbSize _panel) - 1 }; _for do { - private _item = if (_right) then { + // Get item + _item = if (_right) then { _panel lnbData [_i, 0] } else { _panel lbData _i }; - private _quantity = if (_right) then { + + // Get item's count + _quantity = if (_right) then { parseNumber (_panel lnbText [_i, 2]) } else { 0 }; - private _itemCfg = _cfgClass >> _item; + _itemCfg = _cfgClass >> _item; - // In rare cases, item may not belong to the config class for the panel - // For example, misc items panel can contain CfgVehicles and CfgGlasses items in addition to the usual CfgWeapons items + // Some items may not belong to the config class for the panel (misc. items panel can have unique items) if (isNull _itemCfg) then { _itemCfg = _item call CBA_fnc_getItemConfig; }; - private _value = [_itemCfg, _item, _quantity] call _statement; + // Value can be any type + _value = [_itemCfg, _item, _quantity] call _statement; + + // If number, convert to string if (_value isEqualType 0) then { _value = [_value, 8] call CBA_fnc_formatNumber; }; + + // If empty string, add alphabetically small char at beginning to make it sort correctly if (_value isEqualTo "") then { _value = "_"; }; + // Save the current row's item's name in a cache and set text to it's sorting value if (_right) then { - private _name = _panel lnbText [_i, 1]; + _name = _panel lnbText [_i, 1]; _originalNames set [_item, _name]; _panel lnbSetText [[_i, 1], format ["%1%2", _value, _name]]; } else { - if (_item isNotEqualTo "") then { - private _name = _panel lbText _i; + if (_item != "") then { + _name = _panel lbText _i; _originalNames set [_item, _name]; _panel lbSetText [_i, format ["%1%2", _value, _name]]; @@ -157,13 +176,14 @@ _for do { }; }; +// Sort alphabetically, find the previously selected item, select it again and reset text to original text if (_right) then { _panel lnbSort [1, false]; _for do { - private _data = _panel lnbData [_i, 0]; + _data = _panel lnbData [_i, 0]; - if (_curSel >= 0 && {_data == _selected}) then { + if (_curSel != -1 && {_data == _selected}) then { _panel lnbSetCurSelRow _i; }; @@ -173,13 +193,13 @@ if (_right) then { lbSort [_panel, "ASC"]; _for do { - private _data = _panel lbData _i; + _data = _panel lbData _i; - if (_curSel >= 0 && {_data == _selected}) then { + if (_curSel != -1 && {_data == _selected}) then { _panel lbSetCurSel _i; }; - if (_data isNotEqualTo "") then { + if (_data != "") then { _panel lbSetText [_i, _originalNames get _data]; }; }; diff --git a/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf b/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf index 76d75704330..30679752498 100644 --- a/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_accuracy.sqf @@ -14,7 +14,6 @@ params ["_config"]; -private _fireModes = getArray (_config >> "modes"); private _dispersion = []; { @@ -27,7 +26,7 @@ private _dispersion = []; _dispersion pushBackUnique _n; }; -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _dispersion sort true; diff --git a/addons/arsenal/functions/fnc_sortStatement_mod.sqf b/addons/arsenal/functions/fnc_sortStatement_mod.sqf index acba504fc86..2ff4ac77502 100644 --- a/addons/arsenal/functions/fnc_sortStatement_mod.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_mod.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Brett Mayson + * Author: Brett Mayson, johnb43 * Statement to sort items by the mod they belong to. * * Arguments: @@ -14,13 +14,4 @@ params ["_config"]; -private _dlc = ""; -private _addons = configSourceAddonList _config; -if (_addons isNotEqualTo []) then { - private _mods = configSourceModList (configfile >> "CfgPatches" >> _addons select 0); - if (_mods isNotEqualTo []) then { - _dlc = _mods select 0; - }; -}; - -modParams [_dlc, ["name"]] param [0, ""] +(modParams [_config call EFUNC(common,getAddon), ["name"]]) param [0, ""] diff --git a/addons/arsenal/functions/fnc_sortStatement_protection.sqf b/addons/arsenal/functions/fnc_sortStatement_protection.sqf index 463c75e03de..b48bfdc5c87 100644 --- a/addons/arsenal/functions/fnc_sortStatement_protection.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_protection.sqf @@ -15,10 +15,8 @@ */ params ["_itemInfo", "_ballisticCo", "_explosiveCo"]; -_itemInfo params ["_itemCfg"]; +_itemInfo params ["_config"]; -(([[_itemCfg], ["passthrough", "armor"]] call BIS_fnc_configExtremes) select 1) params [["_passthroughMax", 0], ["_armorMax", 0]]; +(([[_config], ["passthrough", "armor"]] call BIS_fnc_configExtremes) select 1) params [["_passthroughMax", 0], ["_armorMax", 0]]; -private _protectionCombined = _passthroughMax * _ballisticCo + _armorMax * _explosiveCo; - -_protectionCombined +_passthroughMax * _ballisticCo + _armorMax * _explosiveCo; diff --git a/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf b/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf index 31f177b09d3..2dd31721a89 100644 --- a/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_rateOfFire.sqf @@ -14,15 +14,15 @@ params ["_config"]; -private _fireModes = getArray (_config >> "modes"); private _fireRate = []; { _fireRate pushBackUnique getNumber (_config >> _x >> "reloadTime"); -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _fireRate sort true; _fireRate = _fireRate param [0, 0]; if (_fireRate == 0) exitWith {0}; + round (60 / _fireRate) diff --git a/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf index 76aedce0062..155bf2d4746 100644 --- a/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf @@ -15,6 +15,7 @@ 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"]; diff --git a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf index 1cd3f149c35..6a00a1982b8 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf @@ -4,11 +4,11 @@ * Accuracy bar statement. * * Arguments: - * 0: stats array (ARRAY) - * 1: item config path (CONFIG) + * 0: Stats array + * 1: Item config path * 2: Args - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Bar limits (ARRAY of SCALAR) + * 2.1: Stat limits + * 2.2: Bar limits * * Return Value: * Number @@ -19,17 +19,19 @@ params ["_stat", "_config", "_args"]; _args params ["_statMinMax", "_barLimits"]; -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;}; + if (!finite _n) then { + _n = 0; + }; + _dispersion pushBackUnique _n; }; -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _dispersion sort true; diff --git a/addons/arsenal/functions/fnc_statBarStatement_default.sqf b/addons/arsenal/functions/fnc_statBarStatement_default.sqf index 4eb0a36f98a..7c4ef4d155d 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_default.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_default.sqf @@ -4,12 +4,12 @@ * 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) + * 0: Stat + * 1: Item config path + * 2: Args + * 2.1: Stat limits + * 2.2: Bar limits + * 2.3: Evaluate as a logarithmic number * * Return Value: * Number diff --git a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf index c8839e85c21..f62eb803217 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf @@ -1,15 +1,15 @@ #include "script_component.hpp" +#include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * 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) + * 0: Stats array + * 1: Item config path + * 2: Args + * 2.1: Stats limits + * 2.2: Bar limits * * Return Value: * Number @@ -18,7 +18,7 @@ */ params ["_stats", "_config", "_args"]; -_args params ["_hitMinMax", "_initSpeedMinMax", "_launcherTabIDC"]; +_args params ["_hitMinMax", "_initSpeedMinMax"]; private _statValues = [ [_config], @@ -31,4 +31,5 @@ private _statValues = [ _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) +// If launcher tab +[sqrt (_hit ^ 2 * _initSpeed), _hit] select (GVAR(currentLeftPanel) == IDC_buttonSecondaryWeapon) diff --git a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf index 6b268a3e56c..21bdde4466a 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf @@ -4,11 +4,11 @@ * Rate of fire bar statement. * * Arguments: - * 0: stats array (ARRAY) - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * 2: Args - * 2.1: Stat limits (ARRAY of BOOL) - * 2.2: Bar limits (ARRAY of SCALAR) + * 2.1: Stat limits + * 2.2: Bar limits * * Return Value: * Number @@ -16,17 +16,20 @@ * Public: No */ -params ["_stat", "_config", "_args"]; +params ["", "_config", "_args"]; _args params ["_statMinMax", "_barLimits"]; -private _fireModes = getArray (_config >> "modes"); private _fireRate = []; { private _n = log (getNumber (_config >> _x >> "reloadTime")); - if (!finite _n) then {_n = 0;}; + + if (!finite _n) then { + _n = 0; + }; + _fireRate pushBackUnique _n; -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _fireRate sort true; diff --git a/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf index cb2687097b9..45118355aa3 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_accuracy.sqf @@ -1,34 +1,30 @@ #include "script_component.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * 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) + * 0: Not used + * 1: Item config path * * Return Value: - * Number + * Stat Text * * Public: No */ -params ["_stat", "_config", "_args"]; -_args params ["_statMinMax", "_configExtremeBool"]; +params ["", "_config"]; +TRACE_1("statTextStatement_accuracy",_config); -private _fireModes = getArray (_config >> "modes"); private _dispersion = []; { if (getNumber (_config >> _x >> "showToPlayer") != 0) then { _dispersion pushBackUnique (getNumber (_config >> _x >> "dispersion")); }; -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _dispersion sort true; _dispersion = _dispersion param [0, 0]; -format ["%1 MIL (%2 MOA)", (_dispersion * 1000) toFixed 2, (_dispersion / pi * 10800) ToFixed 1]; +format ["%1 MIL (%2 MOA)", (_dispersion * 1000) toFixed 2, (_dispersion / pi * 10800) toFixed 1]; diff --git a/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf b/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf index feaec392762..3980f26aa10 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_explosionTime.sqf @@ -4,8 +4,8 @@ * Text statement for the explosion time stat. * * Arguments: - * 0: Stats Array (not used) - * 1: Item Config + * 0: Not used + * 1: Item config path * * Return Value: * Stat Text @@ -17,17 +17,19 @@ */ params ["", "_config"]; +TRACE_1("statTextStatement_explosionTime",_config); private _ammoConfig = configFile >> "CfgAmmo" >> getText (_config >> "ammo"); private _timeToLive = getNumber (_ammoConfig >> "timeToLive"); private _explosionTime = getNumber (_ammoConfig >> "explosionTime"); +// Handle IR grenades if (_explosionTime > _timeToLive) exitWith { - "-" // Handle IR grenades + "-" }; if (_explosionTime == -1) exitWith { - localize LSTRING(DetonatesOnImpact) + LLSTRING(DetonatesOnImpact) }; format ["%1s", _explosionTime] diff --git a/addons/arsenal/functions/fnc_statTextStatement_mass.sqf b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf index 187c5b74c28..341a0f9cb02 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_mass.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_mass.sqf @@ -4,16 +4,17 @@ * Text statement for the mass stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ params ["", "_config"]; +TRACE_1("statTextStatement_mass",_config); private _mass = getNumber (_config >> "mass"); @@ -25,4 +26,4 @@ if (_mass == 0 && {isClass (_config >> "WeaponSlotsInfo")}) then { _mass = getNumber (_config >> "WeaponSlotsInfo" >> "mass"); }; -format ["%1kg (%2lb)",((_mass * 0.1 * (1/2.2046) * 100) / 100) ToFixed 2, ((_mass * 0.1 * 100) / 100) ToFixed 2] +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 index edc6fafc9b2..2175a5651a4 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_rateOfFire.sqf @@ -4,30 +4,27 @@ * Rate of fire 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) + * 0: Not used + * 1: Item config path * * Return Value: - * String + * Stat Text * * Public: No */ -params ["_stat", "_config", "_args"]; -_args params ["_statMinMax", "_configExtremeBool"]; +params ["", "_config"]; +TRACE_1("statTextStatement_rateOfFire",_config); -private _fireModes = getArray (_config >> "modes"); private _fireRate = []; { _fireRate pushBackUnique (getNumber (_config >> _x >> "reloadTime")); -} foreach _fireModes; +} forEach (getArray (_config >> "modes")); _fireRate sort true; _fireRate = _fireRate param [0, 0]; if (_fireRate == 0) exitWith {"PEWPEWPEW"}; + format ["%1 rpm", round (60 / _fireRate)] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf index f817ff6c3fd..681d76aab18 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeMag.sqf @@ -4,11 +4,11 @@ * Text statement for the scope magnification stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ @@ -17,10 +17,11 @@ params ["", "_config"]; TRACE_1("statTextStatement_scopeMag",_config); private _minZoom = 999; // FOV, so smaller is more zoomed in + { _minZoom = _minZoom min (getNumber (_x >> "opticsZoomMin")); } forEach configProperties [_config >> "ItemInfo" >> "OpticsModes"]; if (_minZoom in [0, 999]) exitWith {"?"}; -format ["%1x", (0.25/_minZoom) toFixed 1] +format ["%1x", (0.25 / _minZoom) toFixed 1] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf index 9d6350e2b67..e29fa9cf90b 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" /* - * Author: Dedmen + * Author: Dedmen, johnb43 * Text statement for the scope Night vision support stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ @@ -17,12 +17,12 @@ params ["", "_config"]; TRACE_1("statTextStatement_scopeVisionMode",_config); private _opticsModes = ("true" configClasses (_config >> "ItemInfo" >> "OpticsModes")) apply { - private _visionMode = getArray (_x >> "visionMode"); + private _visionMode = getArray (_x >> "visionMode") apply {toLower _x}; [ - getNumber (_x >> "useModelOptics") == 1, //is in optics - _visionMode isEqualTo [], //optional NVG - "NVG" in _visionMode, //Integrated NVG - "Ti" in _visionMode //Integrated Thermal + getNumber (_x >> "useModelOptics") == 1, // Is in optics + _visionMode isEqualTo [], // Optional NVG + "nvg" in _visionMode, // Integrated NVG + "ti" in _visionMode // Integrated Thermal ] }; @@ -33,30 +33,33 @@ private _secondaryNVGSupported = false; { _x params ["_isPrimary", "_optionalNvg", "_integratedNVG", "_integratedTi"]; + if (_isPrimary) then { if (_integratedNVG) then { _primaryNVGIntegrated = true; }; + if (_optionalNvg) then { _primaryNVGSupported = true; }; + if (_integratedTi) then { _primaryTiIntegrated = true; }; } else { if (_optionalNvg) then { _secondaryNVGSupported = true; - } - } + }; + }; } forEach _opticsModes; -//Detecting Primary by useModelOptics works in 99.9% of cases. -//But on some scopes (from one specific mod) even the primary mode has useModelOptics=false -//So we have this workaround +// Detecting Primary by useModelOptics works in 99.9% of cases. +// But on some scopes (from one specific mod) even the primary mode has useModelOptics=false +// So we have this workaround if ( - count _opticsModes == 1 || //If we only have a single mode. And it's a secondary, then consider it primary. - {{_x select 1} count _opticsModes == count _opticsModes} //If every mode supports it. Then then the primary also supports it + count _opticsModes == 1 || // If we only have a single mode. And it's a secondary, then consider it primary. + {{_x select 1} count _opticsModes == count _opticsModes} // If every mode supports it. Then then the primary also supports it ) then { _primaryNVGSupported = _secondaryNVGSupported; }; diff --git a/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf b/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf index edbcc715ae2..e34dd98beb5 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_smokeChemTTL.sqf @@ -4,22 +4,22 @@ * Text statement for the smoke / chemlight time to live stat. * * Arguments: - * 0: not used - * 1: item config path (CONFIG) + * 0: Not used + * 1: Item config path * * Return Value: - * String to display + * Stat Text * * Public: No */ params ["", "_config"]; +TRACE_1("statTextStatement_smokeChemTTL",_config); private _TTL = getNumber (configFile >> "CfgAmmo" >> getText (_config >> "ammo") >> "timeToLive"); if (_TTL > 3600) then { - - _TTL = _TTL / 60^2; + _TTL = _TTL / 3600; _TTL = str _TTL splitString "."; if (count _TTL > 1) then { @@ -35,6 +35,5 @@ if (_TTL > 3600) then { ] }; } else { - - format ["%1m", round (_TTL / 60)]; + format ["%1m", round (_TTL / 60)] }; diff --git a/addons/arsenal/functions/fnc_updateCamPos.sqf b/addons/arsenal/functions/fnc_updateCamPos.sqf index 66bad379369..1455f664840 100644 --- a/addons/arsenal/functions/fnc_updateCamPos.sqf +++ b/addons/arsenal/functions/fnc_updateCamPos.sqf @@ -10,12 +10,16 @@ * Return Value: * None * + * Example: + * call ace_arsenal_fnc_updateCamPos + * * Public: Yes */ -GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV"]; -[GVAR(cameraHelper), [_dirH + 180, - _dirV, 0]] call bis_fnc_setobjectrotation; -GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; //--- Reattach for smooth movement +GVAR(cameraPosition) params ["_distance", "_dirH", "_dirV"]; + +[GVAR(cameraHelper), [_dirH + 180, - _dirV, 0]] call BIS_fnc_setObjectRotation; +GVAR(cameraHelper) attachTo [GVAR(center), GVAR(cameraPosition) select 3, ""]; // Reattach for smooth movement GVAR(camera) setPos (GVAR(cameraHelper) modelToWorld [0, -_distance, 0]); GVAR(camera) setVectorDirAndUp [vectorDir GVAR(cameraHelper), vectorUp GVAR(cameraHelper)]; diff --git a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf new file mode 100644 index 00000000000..97b3f968bad --- /dev/null +++ b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf @@ -0,0 +1,81 @@ +#include "script_component.hpp" +#include "..\defines.hpp" +/* + * Author: johnb43 + * Updates the list of current items. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +GVAR(currentItems) = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", [], [], [], [], [], [], []]; + +private _isWeapon = false; +private _indexCurrentItems = -1; + +// Add the items the player has to currentItems +{ + switch (_forEachIndex) do { + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + _x params [["_weapon", ""], ["_muzzle", ""], ["_flashlight", ""], ["_optics", ""], ["_primaryMagazine", []], ["_secondaryMagazine", []], ["_bipod", ""]]; + + _weapon = _weapon call EFUNC(common,baseWeapon); + _isWeapon = _forEachIndex != IDX_LOADOUT_BINO; + + // If bino, add it in a different place than regular weapons + GVAR(currentItems) set [[IDX_CURR_BINO, _forEachIndex] select _isWeapon, _weapon]; + + _indexCurrentItems = [IDX_CURR_BINO_ITEMS, IDX_CURR_PRIMARY_WEAPON_ITEMS + _forEachIndex] select _isWeapon; + + // Add weapon attachments + { + (GVAR(currentItems) select _indexCurrentItems) set [[2, 1, 0, 3] select _forEachIndex, _x]; + } forEach [_optics, _flashlight, _muzzle, _bipod]; + + // Add magazines + { + // Magazines are at index 4 & 5 in array -> That's why +4 + (GVAR(currentItems) select _indexCurrentItems) set [_forEachIndex + 4, _x param [0, ""]]; + } forEach [_primaryMagazine, _secondaryMagazine]; + }; + // Uniform + case IDX_LOADOUT_UNIFORM: { + GVAR(currentItems) set [IDX_CURR_UNIFORM, _x param [0, ""]]; + GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, _x param [1, []]]; + }; + // Vest + case IDX_LOADOUT_VEST: { + GVAR(currentItems) set [IDX_CURR_VEST, _x param [0, ""]]; + GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, _x param [1, []]]; + }; + // Backpack + case IDX_LOADOUT_BACKPACK: { + GVAR(currentItems) set [IDX_CURR_BACKPACK, _x param [0, ""]]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, _x param [1, []]]; + }; + // Helmet + case IDX_LOADOUT_HEADGEAR: { + GVAR(currentItems) set [IDX_CURR_HEADGEAR, _x]; + }; + // Facewear + case IDX_LOADOUT_GOGGLES: { + GVAR(currentItems) set [IDX_CURR_GOGGLES, _x]; + }; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + { + // Order of storing virtualItems is different than what getUnitLoadout returns, so do some math + GVAR(currentItems) set [IDX_CURR_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex), _x]; + } forEach _x; + }; + }; +} forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout diff --git a/addons/arsenal/functions/fnc_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf index 8114b8a5681..99e7dc2465a 100644 --- a/addons/arsenal/functions/fnc_updateRightPanel.sqf +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -1,12 +1,13 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Update the right panel (listnbox). * * Arguments: * 0: Right panel control - * 1: Max load of the current container + * 1: Container + * 2: If container has items * * Return Value: * None @@ -14,44 +15,42 @@ * Public: No */ -params ["_control", "_maxLoad"]; +params ["_control", "_container", "_hasItems"]; -private _loadIndicatorBarCtrl = _display displayCtrl IDC_loadIndicatorBar; -private _curSel = lnbCurSelRow _control; - -(lnbSize _control) params ["_rows"]; +private _loadRemaining = maxLoad _container - loadAbs _container; -_maxLoad = getnumber (configfile >> "CfgVehicles" >> _maxLoad >> "maximumLoad"); -_maxLoad = _maxLoad * (1 - (progressPosition _loadIndicatorBarCtrl)); -_maxLoad = parseNumber (_maxLoad toFixed 2); // Required to avoid an issue where even though the typename returns "SCALAR" it doesn't act as one. +private _mass = -1; +private _color = []; -// Grey out items too big -for "_r" from 0 to (_rows - 1) do { - private _mass = _control getVariable (_control lnbData [_r, 0]); - private _class = _control lnbText [_r, 1]; +// Grey out items that are too big to fit in remaining space of the container +for "_row" from 0 to (lnbSize _control select 0) - 1 do { + _mass = _control getVariable (_control lnbData [_row, 0]); - private _alpha = [0.25, 1.0] select (_mass <= _maxLoad); - private _color = [1, 1, 1, _alpha]; - _control lnbSetColor [[_r, 1],_color]; - _control lnbSetColor [[_r, 2],_color]; + // Lower alpha on color for items that can't fit + _color = [1, 1, 1, [0.25, 1] select (_mass <= _loadRemaining)]; + _control lnbSetColor [[_row, 1], _color]; + _control lnbSetColor [[_row, 2], _color]; }; -// Remove all from container show / hide +private _display = ctrlParent _control; + +// If there are items inside container, show "remove all" button private _removeAllCtrl = _display displayCtrl IDC_buttonRemoveAll; -if (progressPosition _loadIndicatorBarCtrl > 0) then { +// A separate "_hasItems" argument is needed, because items can have no mass +_removeAllCtrl ctrlSetFade 0; +_removeAllCtrl ctrlShow _hasItems; +_removeAllCtrl ctrlEnable _hasItems; +_removeAllCtrl ctrlCommit FADE_DELAY; - _removeAllCtrl ctrlSetFade 0; - _removeAllCtrl ctrlShow true; - _removeAllCtrl ctrlEnable true; - _removeAllCtrl ctrlCommit FADE_DELAY; -}; +// Update weight display +(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", GVAR(center) call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); -(_display displayCtrl IDC_totalWeightText) ctrlSetText (format ["%1 (%2)", [GVAR(center), 2] call EFUNC(common,getWeight), [GVAR(center), 1] call EFUNC(common,getWeight)]); +private _curSel = lnbCurSelRow _control; -// change button color if unique or too big +// Disable '+' button if item is unique or too big to fit in remaining space if (_curSel != -1) then { private _plusButtonCtrl = _display displayCtrl IDC_arrowPlus; - _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_control getVariable (_control lnbData [_curSel, 0])) > _maxLoad}); + _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_control getVariable (_control lnbData [_curSel, 0])) > _loadRemaining}); _plusButtonCtrl ctrlCommit FADE_DELAY; }; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index e0aec742737..113d2ca69c7 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -1,8 +1,9 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Update the list of unique items. + * Author: Alganthe, johnb43 + * Updates the list of unique items. + * Unique items are items that can't be multiplied using the arsenal. * * Arguments: * None @@ -13,106 +14,103 @@ * Public: No */ -GVAR(virtualItems) set [18, []]; -GVAR(virtualItems) set [19, []]; -GVAR(virtualItems) set [20, []]; -GVAR(virtualItems) set [21, []]; -GVAR(virtualItems) set [22, [[], [], [], []]]; -GVAR(virtualItems) set [23, []]; -GVAR(virtualItems) set [24, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_MISC_ITEMS, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GRENADES, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_EXPLOSIVES, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_ATTACHMENTS, [[], [], [], []]]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_BACKPACKS, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GOGGLES, []]; -private _array = LIST_DEFAULTS select IDX_VIRT_ITEMS_ALL; -private _itemsCache = uiNamespace getVariable QGVAR(configItems); +private _configItems = uiNamespace getVariable QGVAR(configItems); -private _configCfgWeapons = configFile >> "CfgWeapons"; -private _configMagazines = configFile >> "CfgMagazines"; -private _configVehicles = configFile >> "CfgVehicles"; -private _configGlasses = configFile >> "CfgGlasses"; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgGlasses = configFile >> "CfgGlasses"; + +private _isMagazine = false; +private _isWeapon = false; { - switch true do { - // Weapon mag + _isMagazine = isClass (_cfgMagazines >> _x); + _isWeapon = isClass (_cfgWeapons >> _x); + + switch (true) do { + // Primary, Handgun, Secondary weapon magazines case ( - isClass (_configMagazines >> _x) && - {_x in (_itemsCache select 2)} && - {!(_x in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL))} - ): { - (GVAR(virtualItems) select 19) pushBackUnique _x; + _isMagazine && + {!(_x in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL))} && + {_x in (_configItems select IDX_VIRT_ITEMS_ALL)} + ): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) pushBackUnique _x; }; - - // Mag throw + // Grenades case ( - isClass (_configMagazines >> _x) && - {_x in (_itemsCache select 15)} && - {!(_x in (GVAR(virtualItems) select 15))} - ): { - (GVAR(virtualItems) select 20) pushBackUnique _x; + _isMagazine && + {!(_x in (GVAR(virtualItems) select IDX_VIRT_GRENADES))} && + {_x in (_configItems select IDX_VIRT_GRENADES)} + ): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GRENADES) pushBackUnique _x; }; - - // Mag put + // Explosives case ( - isClass (_configMagazines >> _x) && - {_x in (_itemsCache select 16)} && - {!(_x in (GVAR(virtualItems) select 16))} - ): { - (GVAR(virtualItems) select 21) pushBackUnique _x; + _isMagazine && + {!(_x in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES))} && + {_x in (_configItems select IDX_VIRT_EXPLOSIVES)} + ): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_EXPLOSIVES) pushBackUnique _x; }; - - // acc + // Optics case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHEMENTS) select 0))} && - {_x in ((_itemsCache select 1) select 0)} - ): { - ((GVAR(virtualItems) select 22) select 0) pushBackUnique _x; + _isWeapon && + {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS))} && + {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS)} + ): { + ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS) pushBackUnique _x; }; - - // acc + // Flashlights case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHEMENTS) select 1))} && - {_x in ((_itemsCache select 1) select 1)} - ): { - ((GVAR(virtualItems) select 22) select 1) pushBackUnique _x; + _isWeapon && + {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && + {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} + ): { + ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) pushBackUnique _x; }; - - // acc + // Muzzle attachments case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHEMENTS) select 2))} && - {_x in ((_itemsCache select 1) select 2)} - ): { - ((GVAR(virtualItems) select 22) select 2) pushBackUnique _x; + _isWeapon && + {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS))} && + {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS)} + ): { + ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS) pushBackUnique _x; }; - // acc + // Bipods case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHEMENTS) select 3))} && - {_x in ((_itemsCache select 1) select 3)} - ): { - ((GVAR(virtualItems) select 22) select 3) pushBackUnique _x; + _isWeapon && + {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS))} && + {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS)} + ): { + ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS) pushBackUnique _x; }; - - // Misc + // Misc. items case ( - isClass (_configCfgWeapons >> _x) && - {!(_x in (GVAR(virtualItems) select 17))} && - {!(_x in ((_itemsCache select 1) select 0))} && - {!(_x in ((_itemsCache select 1) select 1))} && - {!(_x in ((_itemsCache select 1) select 2))} && - {!(_x in ((_itemsCache select 1) select 3))} - ): { - (GVAR(virtualItems) select 18) pushBackUnique _x; + _isWeapon && + {!(_x in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS))} && + {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS))} && + {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && + {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS))} && + {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS))} + ): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) pushBackUnique _x; }; - // Backpacks - case (getNumber (_configVehicles >> _x >> "isBackpack") == 1): { - (GVAR(virtualItems) select 23) pushBackUnique _x; + case (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) pushBackUnique _x; }; - // Facewear - case (isClass (_configGlasses >> _x)): { - (GVAR(virtualItems) select 24) pushBackUnique _x; + case (isClass (_cfgGlasses >> _x)): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) pushBackUnique _x; }; }; -} foreach _array; +} forEach (uniformItems GVAR(center) + vestItems GVAR(center) + backpackItems GVAR(center)); diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index e50a583a756..d4c4164efef 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe - * Verify the provided loadout. + * Author: Alganthe, johnb43 + * Verify the provided loadout: Check what items do not exist and what items aren't available in current arsenal. * * Arguments: * 0: Loadout (CBA Extended Loadout or getUnitLoadout format) @@ -23,220 +23,289 @@ if (count _loadout == 2) then { _loadout = _loadout select 0; }; -private _weaponCfg = configFile >> "CfgWeapons"; -private _magCfg = configFile >> "CfgMagazines"; -private _vehcCfg = configFile >> "CfgVehicles"; -private _glassesCfg = configFile >> "CfgGlasses"; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgVehicles = configFile >> "CfgVehicles"; +private _cfgGlasses = configFile >> "CfgGlasses"; + private _weaponsArray = GVAR(virtualItems) select IDX_VIRT_WEAPONS; -private _accsArray = GVAR(virtualItems) select IDX_VIRT_ATTACHEMENTS; +private _accsArray = GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS; private _nullItemsAmount = 0; private _unavailableItemsAmount = 0; private _nullItemsList = []; private _unavailableItemsList = []; -private _fnc_weaponCheck = { - params ["_dataPath"]; - - if (count _dataPath != 0) then { - { - if (_x isEqualType "") then { - - private _item = _x; - - if (_item != "") then { - if (isClass (_weaponCfg >> _item)) then { - if !(CHECK_WEAPON_OR_ACC) then { - - _unavailableItemsList pushBackUnique _item; - _dataPath set [_forEachIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - _dataPath set [_forEachIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; - }; +// Search for all items and turn them into config case; Don't touch other value types +private _fnc_toConfigCase = { + _this apply { + if (_x isEqualType "") then { + if (_x != "") then { + private _name = _x call EFUNC(common,getConfigName); + + // If item doesn't exist in config, "" is returned + // Just return unaltered item name in that case, so it can be documented as being unavailable + if (_name != "") then { + _name + } else { + _x }; - } else { + _x + }; + } else { + // Handle arrays + if (_x isEqualType []) then { + _x call _fnc_toConfigCase + } else { + // All other types + _x + }; + }; + }; +}; - if (count _x != 0) then { - private _mag = _x select 0; - - if (isClass (_magCfg >> _mag)) then { - if !(_mag in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL)) then { - - _unavailableItemsList pushBackUnique _mag; - _dataPath set [_forEachIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { +// Convert loadout to config case +// Loadout might come from a different modpack, which might have different config naming +_loadout = _loadout call _fnc_toConfigCase; - _nullItemsList pushBackUnique _mag; - _dataPath set [_forEachIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; +// Check a weapon, with its attachments and magazines, if items are available +private _fnc_weaponCheck = { + params ["_weaponArray", ["_index", -1]]; + + { + // Weapons and attachments + if (_x isEqualType "") then { + if (_x != "") then { + // Check if item exists + if (isClass (_cfgWeapons >> _x)) then { + // Check if item is available in arsenal + if !( + // Weapon class name is at the very start of the array + if (_forEachIndex == 0) then { + // If the type of weapon is known, only look through that array + if (_index != -1) then { + // If binos, choose differently + if (_index == IDX_LOADOUT_BINO) then { + _x in (GVAR(virtualItems) select IDX_VIRT_BINO) + } else { + _x in (_weaponsArray select _index) + }; + } else { + _x in (_weaponsArray select IDX_VIRT_PRIMARY_WEAPONS) || + {_x in (_weaponsArray select IDX_VIRT_SECONDARY_WEAPONS)} || + {_x in (_weaponsArray select IDX_VIRT_HANDGUN_WEAPONS)} || + {_x in (GVAR(virtualItems) select IDX_VIRT_BINO)} + }; + } else { + _x in (_accsArray select IDX_VIRT_OPTICS_ATTACHMENTS) || + {_x in (_accsArray select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || + {_x in (_accsArray select IDX_VIRT_MUZZLE_ATTACHMENTS)} || + {_x in (_accsArray select IDX_VIRT_BIPOD_ATTACHMENTS)} + } + ) then { + _unavailableItemsList pushBackUnique _x; + _weaponArray set [_forEachIndex, ""]; + INC(_unavailableItemsAmount); }; + } else { + _nullItemsList pushBackUnique _x; + _weaponArray set [_forEachIndex, ""]; + INC(_nullItemsAmount); }; }; - } foreach _dataPath; - }; + } else { + // Magazines + if (_x isNotEqualTo []) then { + _x params ["_magazine"]; + + // Check if item exists + if (isClass (_cfgMagazines >> _magazine)) then { + // Check if item is available in arsenal + if !(_magazine in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL)) then { + _unavailableItemsList pushBackUnique _magazine; + _weaponArray set [_forEachIndex, []]; + INC(_unavailableItemsAmount); + }; + } else { + _nullItemsList pushBackUnique _magazine; + _weaponArray set [_forEachIndex, []]; + INC(_nullItemsAmount); + }; + }; + }; + } forEach _weaponArray; }; -for "_dataIndex" from 0 to 9 do { +private _item = ""; + +// Go through entire loadout to check if items are available in current arsenal +for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do { switch (_dataIndex) do { - case 0; - case 1; - case 2; - case 8: { - [_loadout select _dataIndex] call _fnc_weaponCheck; + // Primary weapon, Secondary weapon, Handgun weapon, Binoculars + case IDX_LOADOUT_PRIMARY_WEAPON; + case IDX_LOADOUT_SECONDARY_WEAPON; + case IDX_LOADOUT_HANDGUN_WEAPON; + case IDX_LOADOUT_BINO: { + [_loadout select _dataIndex, _dataIndex] call _fnc_weaponCheck; }; + // Uniform, vest, backpack + case IDX_LOADOUT_UNIFORM; + case IDX_LOADOUT_VEST; + case IDX_LOADOUT_BACKPACK: { + (_loadout select _dataIndex) params [["_item", ""], ["_containerItems", []]]; - case 3; - case 4; - case 5: { - private _containerArray = (_loadout select _dataIndex); - - if (count _containerArray != 0) then { - - _containerArray params ["_item", "_containerItems"]; - - if (isClass (_vehcCfg >> _item) || {isClass (_weaponCfg >> _item)}) then { - if !(CHECK_CONTAINER) then { - + if (_item != "") then { + // Check if item exists + if (isClass (_cfgVehicles >> _item) || {isClass (_cfgWeapons >> _item)}) then { + // Check if item is available in arsenal + if !(_item in (GVAR(virtualItems) select (_dataIndex + 1))) then { _unavailableItemsList pushBackUnique _item; _loadout set [_dataIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; + INC(_unavailableItemsAmount); } else { - - if (count _containerItems != 0) then { - { - private _currentIndex = _forEachIndex; - - switch (count _x) do { - case 2: { - - if ((_x select 0) isEqualType "") then { - - private _item = _x select 0; - - if (CLASS_CHECK_ITEM) then { - if !(CHECK_CONTAINER_ITEMS) then { - - _unavailableItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; - }; - } else { - - [(((_loadout select _dataIndex) select 1) select _currentIndex) select 0] call _fnc_weaponCheck; + { + switch (true) do { + // Magazines have each 3 entries: Name, number of magazines and ammo count + case (_x isEqualTypeArray ["", 0, 0]): { + _x params ["_item"]; + + // Check if item exists + if (isClass (_cfgMagazines >> _item)) then { + // Check if item is available in arsenal + if !( + _item in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) || + {_item in (GVAR(virtualItems) select IDX_VIRT_GRENADES)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES)} + ) then { + _unavailableItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; + INC(_unavailableItemsAmount); }; + } else { + _nullItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; + INC(_nullItemsAmount); }; - - case 3: { - private _item = _x select 0; - - if (isClass (_magCfg >> _item)) then { - if !( - _item in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) || - _item in (GVAR(virtualItems) select 15) || - _item in (GVAR(virtualItems) select 16) - ) then { - - _unavailableItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; - }; - } else { - - _nullItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_currentIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; + }; + // Weapons have 2 entries: Weapon info array and amount + case (_x isEqualTypeArray [[], 0]): { + [_x select 0] call _fnc_weaponCheck; + }; + // Misc. items have 2 entries: Name and amount, containers have 2 entries: Name and isBackpack + default { + _x params ["_item"]; + + // Check if item exists + if ( + isClass (_cfgWeapons >> _item) || + {isClass (_cfgMagazines >> _item)} || + {isClass (_cfgGlasses >> _item)} || + {isClass (_cfgVehicles >> _item)} + ) then { + // Check if item is available in arsenal + if !( + ////////////////// use _item in GVAR(virtualItemsFlat) ? + _item in (_accsArray select IDX_VIRT_OPTICS_ATTACHMENTS) || + {_item in (_accsArray select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || + {_item in (_accsArray select IDX_VIRT_MUZZLE_ATTACHMENTS)} || + {_item in (_accsArray select IDX_VIRT_BIPOD_ATTACHMENTS)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_HEADGEAR)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_UNIFORM)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_VEST)} ||\ + {_item in (GVAR(virtualItems) select IDX_VIRT_BACKPACK)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_GOGGLES)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_NVG)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_MAP)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_COMPASS)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_RADIO)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_WATCH)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_COMMS)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_GRENADES)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS)} + ) then { + _unavailableItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; + INC(_unavailableItemsAmount); }; + } else { + _nullItemsList pushBackUnique _item; + ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; + INC(_nullItemsAmount); }; }; - } foreach _containerItems; - }; + + }; + } forEach _containerItems; }; } else { - _nullItemsList pushBackUnique _item; _loadout set [_dataIndex, []]; - _nullItemsAmount = _nullItemsAmount + 1; + INC(_nullItemsAmount); }; }; }; - - case 6: { - private _item = _loadout select _dataIndex; + // Headgear + case IDX_LOADOUT_HEADGEAR: { + _item = _loadout select _dataIndex; if (_item != "") then { - - if (isClass (_weaponCfg >> _item)) then { - + // Check if item exists + if (isClass (_cfgWeapons >> _item)) then { + // Check if item is available in arsenal if !(_item in (GVAR(virtualItems) select IDX_VIRT_HEADGEAR)) then { - _unavailableItemsList pushBackUnique _item; _loadout set [_dataIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; + INC(_unavailableItemsAmount); }; } else { - _nullItemsList pushBackUnique _item; _loadout set [_dataIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; + INC(_nullItemsAmount); }; }; }; - - case 7: { - private _item = _loadout select _dataIndex; + // Facewear + case IDX_LOADOUT_GOGGLES: { + _item = _loadout select _dataIndex; if (_item != "") then { - - if (isClass (_glassesCfg >> _item)) then { - + // Check if item exists + if (isClass (_cfgGlasses >> _item)) then { + // Check if item is available in arsenal if !(_item in (GVAR(virtualItems) select IDX_VIRT_GOGGLES)) then { - _unavailableItemsList pushBackUnique _item; _loadout set [_dataIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; + INC(_unavailableItemsAmount); }; } else { - _nullItemsList pushBackUnique _item; _loadout set [_dataIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; + INC(_nullItemsAmount); }; }; }; + // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs + case IDX_LOADOUT_ASSIGNEDITEMS: { + private _assignedItems = _loadout select _dataIndex; - case 9: { for "_subIndex" from 0 to 5 do { - private _item = (_loadout select _dataIndex) select _subIndex; + _item = _assignedItems select _subIndex; if (_item != "") then { - - if (isClass (_weaponCfg >> _item)) then { - - if !(CHECK_ASSIGNED_ITEMS) then { - + // Check if item exists + if (isClass (_cfgWeapons >> _item)) then { + // Check if item is available in arsenal + if !(_item in (GVAR(virtualItems) select (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _subIndex)))) then { _unavailableItemsList pushBackUnique _item; - (_loadout select _dataIndex) set [_subIndex, ""]; - _unavailableItemsAmount = _unavailableItemsAmount + 1; + _assignedItems set [_subIndex, ""]; + INC(_unavailableItemsAmount); }; } else { - _nullItemsList pushBackUnique _item; - (_loadout select _dataIndex) set [_subIndex, ""]; - _nullItemsAmount = _nullItemsAmount + 1; + _assignedItems set [_subIndex, ""]; + INC(_nullItemsAmount); }; }; }; diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf index 8b5f85fba6d..643ba797850 100644 --- a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -8,7 +8,7 @@ cba_diagnostic_projectileMaxLines = 10; [QGVAR(displayOpened), { private _player = player; - // player pose + // Player pose [{ switch (true) do { case (primaryWeapon _this != ""): { @@ -23,15 +23,16 @@ cba_diagnostic_projectileMaxLines = 10; }; }, _player] call CBA_fnc_execNextFrame; - // hide everything except the player + // Hide everything except the player { _x enableSimulation false; _x hideObject true; } forEach (allMissionObjects "" - [_player]); - if ((_player getVariable ["cba_projectile_firedEhId", -1]) != -1) then { + if ((_player getVariable ["CBA_projectile_firedEhId", -1]) != -1) then { _player call CBA_fnc_removeUnitTrackProjectiles; }; + _player setFatigue 0; // Esc to close mission @@ -44,6 +45,7 @@ cba_diagnostic_projectileMaxLines = 10; if (_key isEqualTo DIK_ESCAPE && {!_shift}) then { [_display] spawn { disableSerialization; + params ["_display"]; private _return = [ @@ -54,32 +56,37 @@ cba_diagnostic_projectileMaxLines = 10; ] call BIS_fnc_GUImessage; if (_return) then { - profileNamespace setVariable [QGVAR(missionLastLoadout), [player] call CBA_fnc_getLoadout]; - _display closeDisplay 2; - findDisplay 46 closeDisplay 0; + // Save loadout for next time arsenal mission is played + profileNamespace setVariable [QGVAR(missionLastLoadout), [player] call FUNC(getLoadout)]; + + // Quit mission + _display closeDisplay IDC_CANCEL; + findDisplay IDD_MISSION closeDisplay 0; }; }; + true }; }]; - private _buttonClose = _display displayCtrl IDC_menuBarClose; - _buttonClose ctrlSetText localize "str_a3_rscdisplayarsenal_buttonok"; + (_display displayCtrl IDC_menuBarClose) ctrlSetText localize "str_a3_rscdisplayarsenal_buttonok"; } call CBA_fnc_execNextFrame; }] call CBA_fnc_addEventHandler; [QGVAR(displayClosed), { private _player = player; - // unhide everthing + // Unhide everthing { _x enableSimulation true; _x hideObject false; } forEach allMissionObjects ""; - // update VR unit gear + private _unit = objNull, + + // Update VR unit gear { - private _unit = _x; + _unit = _x; removeVest _unit; _unit addVest vest _player; @@ -95,6 +102,7 @@ cba_diagnostic_projectileMaxLines = 10; removeAllWeapons _unit; _unit addWeapon primaryWeapon _player; + { _unit addPrimaryWeaponItem _x; } forEach primaryWeaponItems _player; @@ -106,6 +114,7 @@ cba_diagnostic_projectileMaxLines = 10; } forEach secondaryWeaponItems _player; _unit addWeapon handgunWeapon _player; + { _unit addHandgunItem _x; } forEach handgunItems _player; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf index 30eac04a7f3..8efb701a170 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -1,18 +1,21 @@ #include "script_component.hpp" params ["_type", "_position", ["_group", grpNull], "_varName"]; + private _player = player; if (isNull _group) then { - _group = creategroup east; + _group = createGroup east; }; -private _target = _group createUnit [_type, [10,10,0], [], 0, "NONE"]; +private _target = _group createUnit [_type, [10, 10, 0], [], 0, "NONE"]; +// _varName is used for respawning unit if (isNil "_varName") then { _varName = _target call BIS_fnc_netId; }; +// Set up AI _target setPos _position; _target setDir (_position getDir _player); _target doWatch position _player; @@ -30,12 +33,15 @@ _target setSpeaker "BASE"; params ["_target", "_time"]; if (speaker _target == "BASE") exitWith {time > _time}; + _target setSpeaker "BASE"; + false }, {}, [_target, time + 1]] call CBA_fnc_waitUntilAndExecute; _player reveal [_target, 4]; +// Copy player's gear onto target _target addVest vest _player; _target addBackpack backpack _player; _target addHeadgear headgear _player; @@ -44,12 +50,14 @@ _target addWeapon primaryWeapon _player; _target addWeapon secondaryWeapon _player; _target addWeapon handgunWeapon _player; +// Save AI for respawn _target setVehicleVarName _varName; -missionNamespace setvariable [_varName, _target]; +missionNamespace setVariable [_varName, _target]; _target switchMove "amovpercmstpslowwrfldnon"; _target setVariable ["origin", _position]; +// When killed, respawn AI _target addEventHandler ["killed", { params ["_target"]; @@ -61,6 +69,7 @@ _target addEventHandler ["killed", { [_target, true] spawn BIS_fnc_VREffectKilled; + // When unit's corpse is deleted, spawn in new one of same type [{isNull (_this select 0)}, { (_this select 1) call FUNC(createTarget); }, [_target, [typeOf _target, _position, group _target, _varName]]] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf index 25e49405bf3..fab59907cc8 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf @@ -1,15 +1,24 @@ #include "script_component.hpp" +#include "..\..\defines.hpp" params ["_display"]; +// Change the abort button to a return button private _ctrlButtonAbort = _display displayCtrl 104; -_ctrlButtonAbort ctrlSetText localize LSTRING(Mission); -_ctrlButtonAbort ctrlSetTooltip localize LSTRING(ReturnToArsenal); +_ctrlButtonAbort ctrlSetText LLSTRING(Mission); +_ctrlButtonAbort ctrlSetTooltip LLSTRING(ReturnToArsenal); _ctrlButtonAbort ctrlSetEventHandler ["ButtonClick", { params ["_control"]; - ctrlParent _control closeDisplay 2; - {[player, player, true] call FUNC(openBox)} call CBA_fnc_execNextFrame; + + // Close pause menu + (ctrlParent _control) closeDisplay IDC_CANCEL; + + // Open the arsenal again + { + [player, player, true] call FUNC(openBox); + } call CBA_fnc_execNextFrame; + true } call EFUNC(common,codeToString)]; diff --git a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf index 7e03a58b08f..3974eb6c71c 100644 --- a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf +++ b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf @@ -4,40 +4,37 @@ params ["_unit"]; private _loadout = profileNamespace getVariable QGVAR(missionLastLoadout); +// Load loadout from previous arsenal mission session if (!isNil "_loadout") then { [_unit, _loadout] call CBA_fnc_setLoadout; }; _unit allowDamage false; -//--- Static targets in various distance +// Static targets at various distances { - private _position = _unit getRelPos [_x, _forEachIndex]; - ["O_Soldier_VR_F", _position] call FUNC(createTarget); + ["O_Soldier_VR_F", _unit getRelPos [_x, _forEachIndex]] call FUNC(createTarget); } forEach [10, 20, 30, 40, 50, 100, 500, 1000, 2000]; -//--- Target line +// Target line to the left of the player private _position = _unit getRelPos [20, -90]; for "_i" from 0 to 5 do { - private _position = _position vectorAdd [0, -3 + _i, 0]; - ["O_Soldier_VR_F", _position] call FUNC(createTarget); + ["O_Soldier_VR_F", _position vectorAdd [0, -3 + _i, 0]] call FUNC(createTarget); }; -//--- Target cluster +// Target cluster to the right of the player _position = _unit getRelPos [20, 90]; for "_i" from 0 to 8 do { private _index = floor (_i / 3); - private _position = _position vectorAdd [_index * 1.5, 1.5 + (_i % 3), 0]; - - private _target = ["O_Soldier_VR_F", _position] call FUNC(createTarget); + private _target = ["O_Soldier_VR_F", _position vectorAdd [_index * 1.5, 1.5 + (_i % 3), 0]] call FUNC(createTarget); _target switchMove (["aidlpercmstpslowwrfldnon", "aidlpknlmstpslowwrfldnon_ai", "aidlppnemstpsraswrfldnon_ai"] select _index); _target setUnitPos (["UP", "MIDDLE", "DOWN"] select _index); }; -//--- Target patrol +// Target patrol: Spawn waypoints around player private _group = createGroup east; { @@ -51,6 +48,7 @@ private _group = createGroup east; _position = _unit getRelPos [10, 180]; +// Spawn in AI for patrol for "_i" from 0 to 1 do { private _target = ["O_Soldier_VR_F", _position] call FUNC(createTarget); @@ -60,11 +58,11 @@ for "_i" from 0 to 1 do { _target setSpeedMode "LIMITED"; }; -//--- Armored vehicles +// Armored vehicles to the rear of the player private _vehicles = []; private _step = 15; -_position = [position _unit select 0,(position _unit select 1) + 30,0]; +_position = _unit getRelPos [30, 180]; { private _row = _forEachIndex; @@ -93,23 +91,29 @@ _position = [position _unit select 0,(position _unit select 1) + 30,0]; "Land_VR_Target_MBT_01_cannon_F" ]]; -_vehicles spawn { - waituntil { - private _allDisabled = true; +private _massDestructionAchieved = getStatValue "MarkMassVirtualDestruction"; - { - _hitAlive = _x getVariable ["bis_fnc_VRHitParts_hitalive", []]; - _allDisabled = _allDisabled && ({!_x} count _hitAlive >= 2); - sleep 0.1; - } forEach _this; +// Don't check for achievement conditions if achievement already aquired +if (!isNil "_massDestructionAchieved" && {_massDestructionAchieved isEqualTo 1}) then { + _vehicles spawn { + waitUntil { + private _allDisabled = true; - _allDisabled - }; + { + _hitAlive = _x getVariable ["BIS_fnc_VRHitParts_hitalive", []]; + _allDisabled = _allDisabled && ({!_x} count _hitAlive >= 2); + + sleep 0.1; + } forEach _this; - setStatValue ["MarkMassVirtualDestruction", 1]; + _allDisabled + }; + + setStatValue ["MarkMassVirtualDestruction", 1]; + }; }; -//--- Cover objects +// Cover objects private _coverObjects = [ "Land_VR_CoverObject_01_kneel_F", "Land_VR_CoverObject_01_kneelHigh_F", @@ -118,33 +122,45 @@ private _coverObjects = [ "Land_VR_CoverObject_01_standHigh_F" ]; +private _coverObjectsCount = count _coverObjects; + +// Set up cover objects for "_i" from 5 to 11 do { private _direction = 180 + _i * 45; private _position = _unit getRelPos [(abs sin _direction + abs cos _direction) * 3, _direction]; - private _block = createVehicle [_coverObjects select (_i % count _coverObjects), _position, [], 0, "NONE"]; + private _block = createVehicle [_coverObjects select (_i % _coverObjectsCount), _position, [], 0, "NONE"]; _block setPos _position; }; -//--- Starting point +// Starting point private _square = createVehicle ["VR_Area_01_square_1x1_grey_F", position _unit, [], 0, "NONE"]; _square setPosASL getPosASL _unit; private _marker = createMarker [QGVAR(start), getPosWorld _unit]; _marker setMarkerType "mil_start"; -//--- Open Arsenal +// Init Arsenal [_unit, true, false] call FUNC(initBox); -[{!isNull findDisplay 46}, { +/* +[{!isNull findDisplay IDD_MISSION}, { [_this, _this, true] call FUNC(openBox); }, _unit] call CBA_fnc_waitUntilAndExecute; +*/ +// Open arsenal when loading screen has finished +["CBA_loadingScreenDone", { + [_thisArgs, _thisArgs, true] call FUNC(openBox); -//--- Salute + // Remove EH + [_thisType, _thisId] call CBA_fnc_removeEventHandler; +}, _unit] call CBA_fnc_addEventHandlerArgs; + + +// Salute _unit addEventHandler ["AnimChanged", { params ["_unit", "_anim"]; - _anim = _anim splitString "_"; - if ("salute" in _anim) then { + if ("salute" in (_anim splitString "_")) then { { _x playAction "salute"; } forEach ((_unit nearObjects ["CAManBase", 10]) - [_unit]); @@ -153,7 +169,7 @@ _unit addEventHandler ["AnimChanged", { ["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0.1, [0,0.5]] spawn BIS_fnc_textTiles; -//--- Target markers +// Target markers private _markers = []; { @@ -164,12 +180,14 @@ private _markers = []; _markers pushBack _marker; } forEach (allMissionObjects "CAManBase" - [_unit]); +// Make the markers move with the targets _markers spawn { while {true} do { { private _target = missionNamespace getVariable _x; _x setMarkerPos position _target; } forEach _this; + sleep 0.1; }; }; diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 02eca6d441d..052505832d1 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -11,12 +11,14 @@ PREP(actionKeysNamesConverted); PREP(addCanInteractWithCondition); PREP(addLineToDebugDraw); PREP(addToInventory); +PREP(addWeapon); PREP(assignedItemFix); PREP(assignObjectsInList); PREP(ambientBrightness); PREP(arithmeticGetResult); PREP(arithmeticSetSource); PREP(ASLToPosition); +PREP(baseWeapon); PREP(binarizeNumber); PREP(blurScreen); PREP(cachedCall); @@ -56,8 +58,10 @@ PREP(fixCollision); PREP(fixFloating); PREP(fixLoweredRifleAnimation); PREP(fixPosition); +PREP(getAddon); PREP(getAllDefinedSetVariables); PREP(getAwakeAnim); +PREP(getConfigName); PREP(getCountOfItem); PREP(getDeathAnim); PREP(getDefaultAnim); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 09e0cf309d5..7f45d74db8c 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -540,7 +540,7 @@ GVAR(deviceKeyCurrentIndex) = -1; [0xC7, [true, false, false]], false] call CBA_fnc_addKeybind; //SHIFT + Home Key -["ACE3 Weapons", QGVAR(unloadWeapon), localize LSTRING(unloadWeapon), { +["ACE3 Weapons", QGVAR(unloadWeapon), LLSTRING(unloadWeapon), { // Conditions: if !([ACE_player, objNull, ["isNotInside"]] call FUNC(canInteractWith)) exitWith {false}; @@ -558,11 +558,8 @@ GVAR(deviceKeyCurrentIndex) = -1; ["CBA_loadoutSet", { params ["_unit", "_loadout"]; - // remove if with https://github.com/CBATeam/CBA_A3/pull/1548 - if (count _loadout == 2) then { - _loadout = _loadout select 0; - }; _loadout params ["_primaryWeaponArray"]; + if ((_primaryWeaponArray param [0, ""]) == "ACE_FakePrimaryWeapon") then { TRACE_1("Ignoring fake gun",_primaryWeaponArray); _loadout set [0, []]; diff --git a/addons/common/XEH_preStart.sqf b/addons/common/XEH_preStart.sqf index 022888575ed..768e5888a79 100644 --- a/addons/common/XEH_preStart.sqf +++ b/addons/common/XEH_preStart.sqf @@ -1,3 +1,13 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// These functions are used for the ace arsenal, one of which are called in preStart (ace_arsenal_fnc_scanConfig) +// Cache for FUNC(getAddon) +uiNamespace setVariable [QGVAR(addonCache), createHashMap]; + +// Cache for FUNC(baseWeapon) +uiNamespace setVariable [QGVAR(baseWeaponNameCache), createHashMap]; + +// Cache for FUNC(getConfigName) +uiNamespace setVariable [QGVAR(configNames), createHashMap]; diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf new file mode 100644 index 00000000000..46536b753ec --- /dev/null +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -0,0 +1,59 @@ +#include "script_component.hpp" +/* + * Author: commy2, johnb43 + * Adds weapon to unit without taking a magazine. + * Same as CBA_fnc_addWeaponWithoutItems, but with some small modifications. + * + * Arguments: + * 0: Unit to add the weapon to + * 1: Weapon to add + * + * Return Value: + * None + * + * Example: + * [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon + * + * Public: Yes +*/ + +params ["_unit", "_weapon"]; + +// Config case +private _compatibleMagazines = compatibleMagazines _weapon; + +private _uniform = uniformContainer _unit; +private _uniformMagazines = (magazinesAmmoCargo _uniform) select { + (_x select 0) in _compatibleMagazines // Also config case +}; + +private _vest = vestContainer _unit; +private _vestMagazines = (magazinesAmmoCargo _vest) select { + (_x select 0) in _compatibleMagazines +}; + +private _backpack = backpackContainer _unit; +private _backpackMagazines = (magazinesAmmoCargo _backpack) select { + (_x select 0) in _compatibleMagazines +}; + +// Remove all compatible magazines +{ + _unit removeMagazines _x; +} forEach _compatibleMagazines; + +// Add weapon +_unit addWeapon _weapon; + +// Add all magazines back +{ + _uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1]; +} forEach _uniformMagazines; + +{ + _vest addMagazineAmmoCargo [_x select 0, 1, _x select 1]; +} forEach _vestMagazines; + +{ + _backpack addMagazineAmmoCargo [_x select 0, 1, _x select 1]; +} forEach _backpackMagazines; diff --git a/addons/common/functions/fnc_baseWeapon.sqf b/addons/common/functions/fnc_baseWeapon.sqf new file mode 100644 index 00000000000..a00ee086d0a --- /dev/null +++ b/addons/common/functions/fnc_baseWeapon.sqf @@ -0,0 +1,62 @@ +#include "script_component.hpp" +/* + * Author: Karel Moricky, johnb43 + * Returns base weapon (weapon without any attachments), but it returns it in config sensitive case. + * Same as BIS_fnc_baseWeapon, except config case and uses cache. + * + * Arguments: + * 0: Weapon + * + * Return Value: + * None + * + * Example: + * ["arifle_AK12_GL_lush_arco_pointer_F"] call ace_common_fnc_baseWeapon + * + * Public: Yes + */ + +params [["_weapon", "", [""]]]; + +private _cacheKey = toLower _weapon; + +// Check if item is cached +private _className = (uiNamespace getVariable QGVAR(baseWeaponNameCache)) get _cacheKey; + +if (!isNil "_className") exitWith { + _className +}; + +private _config = configfile >> "CfgWeapons" >> _weapon; + +// If class doesn't exist, exit +if (!isClass _config) exitWith { + (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _weapon]; + _weapon +}; + +// Get manual base weapon +private _configBase = configfile >> "CfgWeapons" >> getText (_config >> "baseWeapon"); + +if (isClass _configBase) exitWith { + _className = configName _configBase; + (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _className]; + _className +}; + +// Get first parent without any attachments +scopeName "main"; + +// Only take weapons available to the arsenal +while {isClass _config && {getNumber (_config >> "scope") == 2}} do { + if (count (_config >> "LinkedItems") == 0) exitWith { + _className = configName _config; + (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _className]; + _className breakOut "main" + }; + + _config = inheritsFrom _config; +}; + +_cache set [_cacheKey, _weapon]; +_weapon diff --git a/addons/common/functions/fnc_getAddon.sqf b/addons/common/functions/fnc_getAddon.sqf new file mode 100644 index 00000000000..7bdb8a3b433 --- /dev/null +++ b/addons/common/functions/fnc_getAddon.sqf @@ -0,0 +1,39 @@ +#include "script_component.hpp" +/* + * Author: johnb43 + * Returns a config's addon. + * + * Arguments: + * 0: Config entry + * + * Return Value: + * Addon name + * + * Example: + * [configFile >> "CfgWeapons" >> "arifle_AK12_F"] call ace_common_fnc_getConfigName + * + * Public: Yes +*/ + +params ["_config"]; + +// Check if item is cached +private _addon = (uiNamespace getVariable QGVAR(addonCache)) get _config; + +if (!isNil "_addon") exitWith { + _addon +}; + +private _addons = configSourceAddonList _config; + +// Return first addon +_addon = if (_addons isNotEqualTo []) then { + (configSourceModList (configfile >> "CfgPatches" >> _addons select 0)) param [0, ""] +} else { + // If nothing found at all, return "" + "" +}; + +(uiNamespace getVariable QGVAR(addonCache)) set [_config, _addon]; + +_addon diff --git a/addons/common/functions/fnc_getConfigName.sqf b/addons/common/functions/fnc_getConfigName.sqf new file mode 100644 index 00000000000..e04b855b302 --- /dev/null +++ b/addons/common/functions/fnc_getConfigName.sqf @@ -0,0 +1,42 @@ +#include "script_component.hpp" +/* + * Author: johnb43 + * Returns an item's config case sensitive name. + * + * Arguments: + * 0: Class name (item or object) + * + * Return Value: + * Config case item name ("" if config is not found) + * + * Example: + * ["arifle_AK12_F"] call ace_common_fnc_getConfigName + * + * Public: Yes +*/ + +params ["_className"]; + +_className = toLower _className; + +// Check if item is cached +private _configName = (uiNamespace getVariable QGVAR(configNames)) get _className; + +if (!isNil "_configName") exitWith { + _configName +}; + +private _config = configNull; + +{ + _config = configFile >> _x >> _className; + + if (isClass _config) exitWith {}; +} forEach ["CfgWeapons", "CfgMagazines", "CfgGlasses", "CfgVehicles", "CfgVoice", "CfgUnitInsignia"]; + +_configName = configName _config; + +// Save, regardless of its existence +(uiNamespace getVariable QGVAR(configNames)) set [_className, _configName]; + +_configName diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 3d2134e057e..10b8d88bacf 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -118,7 +118,7 @@ Built upon the function of section 2.1, this can be used to make an Arsenal only 3. Clear the debug console then enter the following: ```sqf private _items = flatten (allUnits apply {getUnitLoadout _x}); - _items = _items arrayIntersect _items select {_x isEqualType "" && {_x != ""}}; + _items = (_items arrayIntersect _items) select {_x isEqualType "" && {_x != ""}}; copyToClipboard str _items; ``` @@ -135,7 +135,7 @@ Examples: ACE Arsenal has 2 new config entries for items: - `ace_arsenal_hide`: `0`(shown) or `1` (hidden), used to hide items from ACE Arsenal or `-1` (forced show), for vehicle magazines. -- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout. +- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout. Supports configs in "CfgWeapons", "CfgMagazines" and "CfgVehicles". Item that replaces must be of the same config type as the original item. Both of them are optional. @@ -159,7 +159,7 @@ This loadout list can be exported to the clipboard by using Shift + < | | Argument | Type | Optional (default value) ---| -------- | ---- | ------------------------ 0 | Name of loadout | String | Required -1 | getUnitLoadout array | Array | Required +1 | getUnitLoadout array or CBA extended loadout array | Array | Required Example: `["Squad Leader", getUnitLoadout sql1] call ace_arsenal_fnc_addDefaultLoadout` @@ -193,7 +193,7 @@ class ace_arsenal_stats { The arguments passed to the bar, text and condition statements are: - The stats array `` -- The config entry of the weapon `` +- The config entry of the item `` ### 5.2 Adding stats via a function @@ -216,12 +216,15 @@ The arguments passed to the bar, text and condition statements are: 5.3 | Condition | Code | Required 6 | Priority | Number | Optional (default: `0`) +Return Value: +- Array of stat IDs + Example: ```sqf -[[[0,1,2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { +[[[0, 1, 2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { params ["_statsArray", "_itemCfg"]; getNumber (_itemCfg >> _statsArray select 0) -}, {true}]] call ACE_arsenal_fnc_addStat; +}, {true}]] call ace_arsenal_fnc_addStat; ``` ### 5.3 Removing stats via a function @@ -278,7 +281,74 @@ Right tabs: | 6 | Put | | 7 | Misc | -## 6. Eventhandlers +## 6. Sorting + +ACE Arsenal sorting methods are customizable, this will show you how. + +### 6.1 Adding sorting methods via config + +```cpp +class ace_arsenal_sorts { + class sortBase; + + class TAG_myStat: sortBase { + scope = 2; // Only scope 2 show up in arsenal, scope 1 is used for base classes. + displayName = "Test entry title"; // Title of the sort. + statement = ""; // The returned value will be used to sort alphabetically. The statement's return value is converted to STRING, so anything can be returned by the statement. + condition = "true"; // Condition for the sorts to be displayed, default is true if not defined, needs to return a BOOL. + tabs[] = { {0,1,2}, { } }; // Arrays of tabs, left array is left tabs, right array is right tabs. + }; +}; +``` + +The arguments passed to the statement are: +- The config entry of the item `` +- The item classname `` +- Quantity of items present `` + +The argument passed to the condition is: +- If the sorting occurs in a right panel of uniforms, vest or backpacks. `` + +### 6.2 Adding sorting methods via a function + +`ace_arsenal_fnc_addSort` + +| | Argument | Type | Optional (default value) +--- | -------- | ---- | ------------------------ +0 | Tabs to add the sort to | Array of arrays | Required +0.1 | Left tab indexes | Array of numbers | Required +0.2 | Right tab indexes | Array of numbers | Required +1 | Stat class ID | String | Required +2 | Title | String | Required +3 | Algorithm | Code | Required +4 | Condition | Code | Optional (default: `true`) + +Return Value: +- Array of sort IDs + +Example: +```sqf +[[[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; +``` + +Sorting method IDs are unique and are generated in the same fashion as the stat IDs (see `5.3 Removing stats via a function`). + +### 6.4 Sort tab numbers + +The same numbers are used for sorting methods as for stats (see `5.4 Stat tab numbers`). + +## 7. Eventhandlers All are local. @@ -289,12 +359,12 @@ All are local. | ace_arsenal_leftPanelFilled | Arsenal display (DISPLAY), current left panel IDC (SCALAR), current right panel IDC (SCALAR) | | ace_arsenal_rightPanelFilled | Arsenal display (DISPLAY), current left panel IDC (SCALAR), current right panel IDC (SCALAR) | | ace_arsenal_onLoadoutSave | Loadout index (SCALAR), [loadout name (STRING), loadout data (ARRAY)] | -| ace_arsenal_onLoadoutSaveExtended | Loadout index (SCALAR), [loadout name (STRING), CBA extended loadout data (ARRAY)] | +| ace_arsenal_onLoadoutSaveExtended | Loadout index (SCALAR), [loadout name (STRING), CBA extended loadout data (ARRAY)] | 3.15.1 | ace_arsenal_onLoadoutLoad | loadout data (ARRAY), loadout name (STRING) | -| ace_arsenal_onLoadoutLoadExtended | CBA extended loadout data (ARRAY), loadout name (STRING) | +| ace_arsenal_onLoadoutLoadExtended | CBA extended loadout data (ARRAY), loadout name (STRING) | 3.15.1 | ace_arsenal_onLoadoutDelete | loadout name (STRING) | -| ace_arsenal_loadoutShared | Loadouts list listnBox control (CONTROL),, [loadout author (STRING), loadout name (STRING), loadout data (ARRAY)] | -| ace_arsenal_loadoutUnshared | Loadouts list listnBox control (CONTROL), loadout name (STRING) | +| ace_arsenal_loadoutShared | Loadouts list listnBox control (CONTROL), [loadout author (STRING), loadout name (STRING), loadout data (ARRAY)] | +| ace_arsenal_loadoutUnshared | Loadouts list listnBox control (CONTROL), loadout author (STRING), loadout name (STRING) | | ace_arsenal_cargoChanged | Arsenal display (DISPLAY), item (STRING), add or remove (BOOL), shiftState (BOOL) | | ace_arsenal_loadoutImported | Arsenal display (DISPLAY), (import list (BOOL) | | ace_arsenal_loadoutExported | Arsenal display (DISPLAY), export list (BOOL) | @@ -303,9 +373,9 @@ All are local. | ace_arsenal_loadoutsTabChanged | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 | | ace_arsenal_loadoutsListFilled | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 | -## 7. Custom sub item categories +## 8. Custom sub item categories -### 7.1 Adding a sub item category +### 8.1 Adding a sub item category `ace_arsenal_fnc_addRightPanelButton` @@ -317,11 +387,11 @@ All are local. 3 | Override a specific button | Number | Optional (default: `-1`) Return Value: -- successful: number of the slot (0-9) -- error: -1 +- Successful: Number of the slot (0-9) +- Error: -1 -This function creates a sub category under misc items in the ACE Arsenal. -Only items that are listed under 'Misc Items' are available for sub categories. +This function creates a sub category under misc. items in the ACE Arsenal. +Only items that are listed under 'Misc. Items' are available for sub categories. If the 'Override a specific button' argument is not used, the button will added at the bottom of the rest. Examples: From aef50dd94530fe839efdfcd29799f71253d6894e Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 4 Nov 2022 09:36:24 +0100 Subject: [PATCH 02/24] Fixes --- addons/arsenal/XEH_PREP.hpp | 1 - addons/arsenal/XEH_postInit.sqf | 25 ++++++++++- .../arsenal/functions/fnc_attributeImport.sqf | 1 - addons/arsenal/functions/fnc_buttonExport.sqf | 2 +- .../functions/fnc_buttonLoadoutsSave.sqf | 2 +- addons/arsenal/functions/fnc_getLoadout.sqf | 43 ------------------- .../arsenal/functions/fnc_onArsenalClose.sqf | 2 +- .../arsenal/functions/fnc_onArsenalOpen.sqf | 2 +- addons/arsenal/functions/fnc_scanConfig.sqf | 24 ++--------- .../functions/fnc_updateUniqueItemsList.sqf | 2 +- .../missions/Arsenal.VR/XEH_postInit.sqf | 2 +- .../missions/Arsenal.VR/initPlayerLocal.sqf | 16 ++----- addons/common/functions/fnc_getAddon.sqf | 2 +- 13 files changed, 38 insertions(+), 86 deletions(-) delete mode 100644 addons/arsenal/functions/fnc_getLoadout.sqf diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index d4c96d7ba03..1dc78db024e 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -34,7 +34,6 @@ PREP(fillLeftPanel); PREP(fillLoadoutsList); PREP(fillRightPanel); PREP(fillSort); -PREP(getLoadout); PREP(handleLoadoutsSearchbar); PREP(handleMouse); PREP(handleScrollWheel); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index 6b04af6d922..ccc1c582d75 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -118,7 +118,30 @@ GVAR(lastSortRight) = ""; private _insignia = _extendedInfo getOrDefault [QGVAR(insignia), ""]; if (_insignia != "") then { - [_unit, ""] call BIS_fnc_setUnitInsignia; + _unit setVariable ["BIS_fnc_setUnitInsignia_class", nil]; [_unit, _insignia] call BIS_fnc_setUnitInsignia; }; }] call CBA_fnc_addEventHandler; + +["CBA_loadoutGet", { + params ["_unit", "_loadout", "_extendedInfo"]; + + // Set face if enabled + if (GVAR(loadoutsSaveFace)) then { + _extendedInfo set [QGVAR(face), face _unit]; + }; + + // Set voice if enabled + if (GVAR(loadoutsSaveVoice)) then { + _extendedInfo set [QGVAR(voice), speaker _unit]; + }; + + // Set insignia if enabled + if (GVAR(loadoutsSaveInsignia)) then { + private _insignia = _unit call BIS_fnc_getUnitInsignia; + + if (_insignia != "") then { + _extendedInfo set [QGVAR(insignia), _insignia]; + }; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/arsenal/functions/fnc_attributeImport.sqf b/addons/arsenal/functions/fnc_attributeImport.sqf index fdc3dd8c5f5..878a5e3b9ea 100644 --- a/addons/arsenal/functions/fnc_attributeImport.sqf +++ b/addons/arsenal/functions/fnc_attributeImport.sqf @@ -46,7 +46,6 @@ private _intersection = []; _filteredList append _intersection; - //////////////////////// Is this necessary/wanted? // Remove found entries, to reduce input array size _importList = _importList - _intersection; diff --git a/addons/arsenal/functions/fnc_buttonExport.sqf b/addons/arsenal/functions/fnc_buttonExport.sqf index 167b6c4e57a..fd4568f0250 100644 --- a/addons/arsenal/functions/fnc_buttonExport.sqf +++ b/addons/arsenal/functions/fnc_buttonExport.sqf @@ -44,7 +44,7 @@ if (GVAR(shiftState)) then { [_display, LLSTRING(exportDefault)] call FUNC(message); } else { // Export singular loadout - private _export = str (GVAR(center) call FUNC(getLoadout)); + private _export = str (GVAR(center) call CBA_fnc_getLoadout); "ace_clipboard" callExtension (_export + ";"); "ace_clipboard" callExtension "--COMPLETE--"; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf index c25ef21a7c6..4fce9bb867f 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf @@ -46,7 +46,7 @@ private _loadoutName = _contentPanelCtrl lnbText [_curSelRow, 1]; private _curSelLoadout = (_contentPanelCtrl getVariable (_loadoutName + str GVAR(currentLoadoutsTab))) select 0; // Get unit's current loadout -private _extendedLoadout = GVAR(center) call FUNC(getLoadout); +private _extendedLoadout = GVAR(center) call CBA_fnc_getLoadout; _extendedLoadout params ["_loadout"]; private _loadouts = [profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (is3DEN && {GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts}); diff --git a/addons/arsenal/functions/fnc_getLoadout.sqf b/addons/arsenal/functions/fnc_getLoadout.sqf deleted file mode 100644 index 54767264eaa..00000000000 --- a/addons/arsenal/functions/fnc_getLoadout.sqf +++ /dev/null @@ -1,43 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Brett Mayson - * Get the extended loadout of a unit, including identity options if enabled. - * - * Arguments: - * 0: Unit - * - * Return Value: - * CBA Extended Loadout - * - * Example: - * [_unit] call ace_arsenal_fnc_getLoadout - * - * Public: Yes -*/ - -params [["_unit", objNull, [objNull]]]; - -if (isNull _unit) exitWith {}; - -([_unit] call CBA_fnc_getLoadout) params ["_loadout", "_extendedInfo"]; - -// Set face if enabled -if (GVAR(loadoutsSaveFace)) then { - _extendedInfo set [QGVAR(face), face _unit]; -}; - -// Set voice if enabled -if (GVAR(loadoutsSaveVoice)) then { - _extendedInfo set [QGVAR(voice), speaker _unit]; -}; - -// Set insignia if enabled -if (GVAR(loadoutsSaveInsignia)) then { - private _insignia = _unit call BIS_fnc_getUnitInsignia; - - if (_insignia != "") then { - _extendedInfo set [QGVAR(insignia), _insignia]; - }; -}; - -[_loadout, _extendedInfo] diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 95b367717fc..df5c12d8c0a 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -28,7 +28,7 @@ if (is3DEN) then { // Apply the loadout from the dummy to all selected units if (_exitCode == 1) then { - private _extendedLoadout = GVAR(center) call FUNC(getLoadout); + private _extendedLoadout = GVAR(center) call CBA_fnc_getLoadout; private _objects = get3DENSelected "object"; { diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index 85420b10cc5..cc2db19b505 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -240,7 +240,7 @@ if (is3DEN) then { GVAR(center) switchAction "playerStand"; GVAR(center) enableSimulation false; - [GVAR(center), GVAR(centerOrigin) call FUNC(getLoadout)] call CBA_fnc_setLoadout; + [GVAR(center), GVAR(centerOrigin) call CBA_fnc_getLoadout] call CBA_fnc_setLoadout; //--- Create light for night editing (code based on BIS_fnc_3DENFlashlight) GVAR(light) = "#lightpoint" createVehicle _centerPos; diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 44884dbb247..cbc00fd98ac 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -95,9 +95,9 @@ private _isMiscItem = false; }; // Weapon, at the bottom to avoid adding binos case ( - isClass (_x >> "WeaponSlotsInfo") && - {getNumber (_x >> "type") != TYPE_BINOCULAR_AND_NVG} - ): { + isClass (_x >> "WeaponSlotsInfo") && + {getNumber (_x >> "type") != TYPE_BINOCULAR_AND_NVG} + ): { switch (getNumber (_x >> "type")) do { case TYPE_WEAPON_PRIMARY: { ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); @@ -180,25 +180,8 @@ _putList = _putList - [""]; (_configItems select IDX_VIRT_GOGGLES) pushBackUnique (configName _x); } forEach configProperties [configFile >> "CfgGlasses", _filterFunction, true]; -// Get magazine groups (magazinewells) -private _magazineGroups = createHashMap; -private _magazinesList = []; - -{ - _magazinesList = []; - - { - // Filter out non-existent magazines, then make names config case - /////////////////////////////////////////////////////////////////// No filtering for scope ? - _magazinesList append (((getArray _x) select {isClass (_cfgMagazines >> _x)}) apply {configName (_cfgMagazines >> _x)}); - } forEach configProperties [_x, "isArray _x", true]; - - _magazineGroups set [toLower configName _x, _magazinesList arrayIntersect _magazinesList]; -} forEach configProperties [configFile >> "CfgMagazineWells", "isClass _x", true]; - // Get all faces private _faceCache = createHashMap; - private _dlcName = ""; private _modPicture = ""; @@ -227,7 +210,6 @@ private _insigniaCache = "true" configClasses (configFile >> "CfgUnitInsignia"); // This contains config case entries only uiNamespace setVariable [QGVAR(configItems), _configItems]; uiNamespace setVariable [QGVAR(configItemsFlat), flatten _configItems]; -uiNamespace setVariable [QGVAR(magazineGroups), _magazineGroups]; uiNamespace setVariable [QGVAR(faceCache), _faceCache]; uiNamespace setVariable [QGVAR(voiceCache), _voiceCache]; uiNamespace setVariable [QGVAR(insigniaCache), _insigniaCache]; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 113d2ca69c7..5e942cd299d 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -113,4 +113,4 @@ private _isWeapon = false; (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) pushBackUnique _x; }; }; -} forEach (uniformItems GVAR(center) + vestItems GVAR(center) + backpackItems GVAR(center)); +} forEach ([GVAR(center)] call ace_common_fnc_uniqueItems); diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf index 643ba797850..b7e9027869f 100644 --- a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -57,7 +57,7 @@ cba_diagnostic_projectileMaxLines = 10; if (_return) then { // Save loadout for next time arsenal mission is played - profileNamespace setVariable [QGVAR(missionLastLoadout), [player] call FUNC(getLoadout)]; + profileNamespace setVariable [QGVAR(missionLastLoadout), [player] call CBA_fnc_getLoadout]; // Quit mission _display closeDisplay IDC_CANCEL; diff --git a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf index 3974eb6c71c..324ac7c6180 100644 --- a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf +++ b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf @@ -1,4 +1,5 @@ #include "script_component.hpp" +#include "..\..\defines.hpp" params ["_unit"]; @@ -74,7 +75,7 @@ _position = _unit getRelPos [30, 180]; private _vehicle = createVehicle [_x, _position, [], 0, "NONE"]; _vehicle setPos _position; _vehicle setDir 180; - _vehicle setVelocity [0,0,-1]; + _vehicle setVelocity [0, 0, -1]; _vehicle call BIS_fnc_VRHitpart; private _marker = _vehicle call BIS_fnc_boundingBoxMarker; @@ -142,19 +143,10 @@ _marker setMarkerType "mil_start"; // Init Arsenal [_unit, true, false] call FUNC(initBox); -/* +// Wait until the mission screen is available [{!isNull findDisplay IDD_MISSION}, { [_this, _this, true] call FUNC(openBox); }, _unit] call CBA_fnc_waitUntilAndExecute; -*/ -// Open arsenal when loading screen has finished -["CBA_loadingScreenDone", { - [_thisArgs, _thisArgs, true] call FUNC(openBox); - - // Remove EH - [_thisType, _thisId] call CBA_fnc_removeEventHandler; -}, _unit] call CBA_fnc_addEventHandlerArgs; - // Salute _unit addEventHandler ["AnimChanged", { @@ -167,7 +159,7 @@ _unit addEventHandler ["AnimChanged", { }; }]; -["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0.1, [0,0.5]] spawn BIS_fnc_textTiles; +["#(argb,8,8,3)color(0,0,0,1)", false, nil, 0.1, [0, 0.5]] spawn BIS_fnc_textTiles; // Target markers private _markers = []; diff --git a/addons/common/functions/fnc_getAddon.sqf b/addons/common/functions/fnc_getAddon.sqf index 7bdb8a3b433..acdd3f689b4 100644 --- a/addons/common/functions/fnc_getAddon.sqf +++ b/addons/common/functions/fnc_getAddon.sqf @@ -10,7 +10,7 @@ * Addon name * * Example: - * [configFile >> "CfgWeapons" >> "arifle_AK12_F"] call ace_common_fnc_getConfigName + * [configFile >> "CfgWeapons" >> "arifle_AK12_F"] call ace_common_fnc_getAddon * * Public: Yes */ From d7ea428c6e8753035888ad5bbb9ac378969b05f9 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 31 Jan 2023 11:54:09 +0100 Subject: [PATCH 03/24] Update fnc_onSelChangedLeft.sqf --- addons/arsenal/functions/fnc_onSelChangedLeft.sqf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 05b0fd621d6..56d771dec41 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -291,11 +291,11 @@ switch (GVAR(currentLeftPanel)) do { GVAR(center) setUnitLoadout _loadout; private _uniformItems = uniformItems GVAR(center); - private _index = count _backpackItems - 1; + private _index = count _uniformItems - 1; // Remove any items that can't fit in the container (this prevents overloading) while {loadUniform GVAR(center) > 1} do { - GVAR(center) removeItemFromUniform (_backpackItems select _index); + GVAR(center) removeItemFromUniform (_uniformItems select _index); DEC(_index); }; @@ -331,12 +331,12 @@ switch (GVAR(currentLeftPanel)) do { _loadout set [IDX_LOADOUT_VEST, [_item, GVAR(currentItems) select IDX_CURR_VEST_ITEMS]]; GVAR(center) setUnitLoadout _loadout; - private _backpackItems = vestItems GVAR(center); - private _index = count _backpackItems - 1; + private _vestItems = vestItems GVAR(center); + private _index = count _vestItems - 1; // Remove any items that can't fit in the container (this prevents overloading) while {loadVest GVAR(center) > 1} do { - GVAR(center) removeItemFromVest (_backpackItems select _index); + GVAR(center) removeItemFromVest (_vestItems select _index); DEC(_index); }; From 75d8cc86229bbe66a05c3978f5cc870fb6a17ca2 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 19 May 2023 14:05:28 +0200 Subject: [PATCH 04/24] Update fnc_updateUniqueItemsList.sqf --- addons/arsenal/functions/fnc_updateUniqueItemsList.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 5e942cd299d..6e089e143b6 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -113,4 +113,4 @@ private _isWeapon = false; (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) pushBackUnique _x; }; }; -} forEach ([GVAR(center)] call ace_common_fnc_uniqueItems); +} forEach ([GVAR(center)] call EFUNC(common,uniqueItems)); From 652de706f2ca05b03f0a889a98d0d3197d2bc7c4 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 19 May 2023 16:05:25 +0200 Subject: [PATCH 05/24] Header fixes --- addons/arsenal/functions/fnc_addListBoxItem.sqf | 7 ++++--- addons/arsenal/functions/fnc_addSort.sqf | 4 ++-- addons/arsenal/functions/fnc_addStat.sqf | 10 +++++----- addons/arsenal/functions/fnc_addVirtualItems.sqf | 4 ++-- addons/arsenal/functions/fnc_buttonCargo.sqf | 2 +- addons/arsenal/functions/fnc_buttonStats.sqf | 3 +-- addons/arsenal/functions/fnc_buttonStatsPage.sqf | 5 +++-- addons/arsenal/functions/fnc_clearSearchbar.sqf | 6 +++--- addons/arsenal/functions/fnc_compileSorts.sqf | 2 +- addons/arsenal/functions/fnc_compileStats.sqf | 2 +- addons/arsenal/functions/fnc_handleMouse.sqf | 6 +++--- addons/arsenal/functions/fnc_handleScrollWheel.sqf | 4 ++-- addons/arsenal/functions/fnc_handleStats.sqf | 4 ++-- addons/arsenal/functions/fnc_initBox.sqf | 4 ++-- addons/arsenal/functions/fnc_itemInfo.sqf | 2 +- addons/arsenal/functions/fnc_onArsenalClose.sqf | 5 ++++- addons/arsenal/functions/fnc_onArsenalOpen.sqf | 4 ++-- addons/arsenal/functions/fnc_onLoadoutsOpen.sqf | 4 ++-- addons/arsenal/functions/fnc_onMouseButtonDown.sqf | 12 ++++++++++++ addons/arsenal/functions/fnc_onMouseButtonUp.sqf | 10 ++++++++++ addons/arsenal/functions/fnc_onSelChangedLeft.sqf | 2 +- .../arsenal/functions/fnc_onSelChangedLoadouts.sqf | 4 ++-- addons/arsenal/functions/fnc_onSelChangedRight.sqf | 2 +- addons/arsenal/functions/fnc_open3DEN.sqf | 2 +- addons/arsenal/functions/fnc_openBox.sqf | 2 +- addons/arsenal/functions/fnc_removeBox.sqf | 2 +- addons/arsenal/functions/fnc_removeStat.sqf | 2 +- addons/arsenal/functions/fnc_removeVirtualItems.sqf | 4 ++-- .../arsenal/functions/fnc_sortStatement_amount.sqf | 4 ++-- .../arsenal/functions/fnc_sortStatement_scopeMag.sqf | 2 +- .../functions/fnc_statBarStatement_accuracy.sqf | 10 +++++----- .../functions/fnc_statBarStatement_default.sqf | 6 +++--- .../functions/fnc_statBarStatement_impact.sqf | 6 +++--- .../functions/fnc_statBarStatement_rateOfFIre.sqf | 6 +++--- addons/arsenal/functions/fnc_updateCamPos.sqf | 2 +- 35 files changed, 91 insertions(+), 65 deletions(-) diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index fbbfe08c1d8..3aee41b8e0c 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -7,7 +7,7 @@ * 0: Config category, must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice" * 1: Classname * 2: Panel control - * 3: Name of the picture entry in that Cfg class (Optional) + * 3: Name of the picture entry in that Cfg class (default: "picture") * * Return Value: * None @@ -38,10 +38,11 @@ if (_cachedItemInfo isEqualTo []) then { // Get name of DLC private _dlcName = _configPath call EFUNC(common,getAddon); + // Mod picture if (_dlcName != "") then { - _cachedItemInfo set [3, (modParams [_dlcName, ["logo"]]) param [0, ""]]; // Mod picture + _cachedItemInfo set [3, (modParams [_dlcName, ["logo"]]) param [0, ""]]; } else { - _cachedItemInfo set [3, ""]; // Mod picture + _cachedItemInfo set [3, ""]; }; // Store in cache diff --git a/addons/arsenal/functions/fnc_addSort.sqf b/addons/arsenal/functions/fnc_addSort.sqf index 38cd5b9a96c..cc116823399 100644 --- a/addons/arsenal/functions/fnc_addSort.sqf +++ b/addons/arsenal/functions/fnc_addSort.sqf @@ -4,7 +4,7 @@ * Add a custom sorting method. * * Arguments: - * 0: Tabs to add stat to + * 0: Tabs to add sort to * 0.0: Left Tab Indexes * 0.1: Right Tab Indexes * 1: Sort Class (a unique string for each algorithm) @@ -60,7 +60,7 @@ private _fnc_addToTabs = { } forEach _tabsToAddTo; }; -_finalArray = ["", _title, _statement, _condition]; +private _finalArray = ["", _title, _statement, _condition]; if (_leftTabs isNotEqualTo []) then { [GVAR(sortListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf index b0094ea94d7..71831e656e8 100644 --- a/addons/arsenal/functions/fnc_addStat.sqf +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -11,12 +11,12 @@ * 2: Config entries to pass * 3: Title * 4: Show bar / show text bools - * 4.0: Show bar - * 4.1: Show text + * 4.0: Show bar (default: false) + * 4.1: Show text (default: false) * 5: Array of statements - * 5.0: Bar code - * 5.1: Text code - * 5.2: Condition code + * 5.0: Bar code (default: {}) + * 5.1: Text code (default: {}) + * 5.2: Condition code (default: {true}) * 6: Priority (default: 0) * * Return Value: diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index 71d185ca33c..a694b89fdcc 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -6,8 +6,8 @@ * * Arguments: * 0: Target - * 1: Items - * 2: Add globally (Optional) + * 1: Items + * 2: Add globally (default: false) * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index e03fed40d18..d10cf8da926 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: Arsenal display - * 1: Add or remove (-1: Remove, 1: Add) + * 1: Add (1) or remove (-1) item * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_buttonStats.sqf b/addons/arsenal/functions/fnc_buttonStats.sqf index 08ad8e287c5..34dbfc608ec 100644 --- a/addons/arsenal/functions/fnc_buttonStats.sqf +++ b/addons/arsenal/functions/fnc_buttonStats.sqf @@ -2,11 +2,10 @@ #include "..\defines.hpp" /* * Author: Alganthe - * Toggle the stats control group + * Toggle the stats control group. * * Arguments: * 0: Arsenal display - * 1: Button control * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_buttonStatsPage.sqf b/addons/arsenal/functions/fnc_buttonStatsPage.sqf index 17bc0dfab04..a3ab2607bfe 100644 --- a/addons/arsenal/functions/fnc_buttonStatsPage.sqf +++ b/addons/arsenal/functions/fnc_buttonStatsPage.sqf @@ -2,11 +2,12 @@ #include "..\defines.hpp" /* * Author: Alganthe - * Handles the previous / next page buttons for stats + * Handles the previous / next page buttons for stats. * * Arguments: * 0: Arsenal display - * 1: Previous or next (false = previous, true = next) + * 1: Stats page + * 2: Previous (false) or next (true) page * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_clearSearchbar.sqf b/addons/arsenal/functions/fnc_clearSearchbar.sqf index ac43f92a470..4d9521baca2 100644 --- a/addons/arsenal/functions/fnc_clearSearchbar.sqf +++ b/addons/arsenal/functions/fnc_clearSearchbar.sqf @@ -7,7 +7,7 @@ * Arguments: * 0: Arsenal display * 1: Searchbar control - * 2: Right button state + * 2: Mouse button * * Return Value: * None @@ -15,9 +15,9 @@ * Public: No */ -params ["_display", "_control", "_rightButton"]; +params ["_display", "_control", "_buttonPressed"]; -if (_rightButton != 1) exitWith {}; +if (_buttonPressed != 1) exitWith {}; _control ctrlSetText ""; diff --git a/addons/arsenal/functions/fnc_compileSorts.sqf b/addons/arsenal/functions/fnc_compileSorts.sqf index fd790fa8323..613843e27f4 100644 --- a/addons/arsenal/functions/fnc_compileSorts.sqf +++ b/addons/arsenal/functions/fnc_compileSorts.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Brett Mayson - * Create the internal stats arrays when needed for the first time + * Create the internal sort arrays when needed for the first time. * * Arguments: * None diff --git a/addons/arsenal/functions/fnc_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf index 0639ef99134..34442f946e1 100644 --- a/addons/arsenal/functions/fnc_compileStats.sqf +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Alganthe - * Create the internal stats arrays when needed for the first time + * Create the internal stat arrays when needed for the first time. * * Arguments: * None diff --git a/addons/arsenal/functions/fnc_handleMouse.sqf b/addons/arsenal/functions/fnc_handleMouse.sqf index 9f3f0dccc8b..4f434855e76 100644 --- a/addons/arsenal/functions/fnc_handleMouse.sqf +++ b/addons/arsenal/functions/fnc_handleMouse.sqf @@ -8,9 +8,9 @@ * Arguments: * 0: Not used * 1: Arguments - * 1.1: Mouse area control - * 1.2: Mouse X position - * 1.3: Mouse Y position + * 1.0: Mouse area control + * 1.1: Mouse X position + * 1.2: Mouse Y position * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_handleScrollWheel.sqf b/addons/arsenal/functions/fnc_handleScrollWheel.sqf index 559fec04fc3..ddfb903f380 100644 --- a/addons/arsenal/functions/fnc_handleScrollWheel.sqf +++ b/addons/arsenal/functions/fnc_handleScrollWheel.sqf @@ -6,8 +6,8 @@ * Arguments: * 0: Not used * 1: onMouseZChanged EH return - * 1.1: Not used - * 1.2: Mousewheel Z position + * 1.0: Not used + * 1.1: Mousewheel Z position * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf index 4524cb7cb51..b1e38572ea0 100644 --- a/addons/arsenal/functions/fnc_handleStats.sqf +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -2,12 +2,12 @@ #include "..\defines.hpp" /* * Author: Alganthe - * Handles the stats control group + * Handles the stats control group. * * Arguments: * 0: Arsenal display * 1: Current panel control - * 2: Current panel selection + * 2: Current panel selection * 3: Item config entry * * Return Value: diff --git a/addons/arsenal/functions/fnc_initBox.sqf b/addons/arsenal/functions/fnc_initBox.sqf index da1856b71d5..4139cddf072 100644 --- a/addons/arsenal/functions/fnc_initBox.sqf +++ b/addons/arsenal/functions/fnc_initBox.sqf @@ -5,8 +5,8 @@ * * Arguments: * 0: Target - * 1: Items or - * 2: Initialize globally + * 1: Items + * 2: Initialize globally (default: true) * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf index e0643b49818..710864e3e31 100644 --- a/addons/arsenal/functions/fnc_itemInfo.sqf +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -8,7 +8,7 @@ * Arguments: * 0: Arsenal display * 1: Current panel control - * 2: Current panel selection + * 2: Current panel selection * 3: Item config entry * * Return Value: diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index df5c12d8c0a..d19fc63df07 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -4,7 +4,10 @@ * onUnLoad EH for arsenal. * * Arguments: - * None + * 0: Not used + * 1: Args + * 1.0: Not used + * 1.1: Exit code * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index cc2db19b505..ce717e22cd1 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -5,9 +5,9 @@ * onLoad EH for arsenal. * * Arguments: - * 0: Ignored + * 0: Not used * 1: Arguments - * 1.1: Arsenal display + * 1.0: Arsenal display * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf index 6e2965d60bf..6a0cd1ef5b7 100644 --- a/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf +++ b/addons/arsenal/functions/fnc_onLoadoutsOpen.sqf @@ -5,9 +5,9 @@ * onLoad EH for arsenal loadouts display. * * Arguments: - * 0: Ignored + * 0: Not used * 1: Arguments - * 1.1: Loadouts display + * 1.0: Loadouts display * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_onMouseButtonDown.sqf b/addons/arsenal/functions/fnc_onMouseButtonDown.sqf index a633cab4dd3..1541289e0ef 100644 --- a/addons/arsenal/functions/fnc_onMouseButtonDown.sqf +++ b/addons/arsenal/functions/fnc_onMouseButtonDown.sqf @@ -1,6 +1,18 @@ #include "script_component.hpp" /* * Author: commy2 + * Handles mouse button press. + * + * Arguments: + * 0: Not used + * 1: Args + * 1.0: Not used + * 1.1: Mouse button + * 1.2: Mouse X position + * 1.3: Mouse Y position + * + * Return Value: + * None * * Public: No */ diff --git a/addons/arsenal/functions/fnc_onMouseButtonUp.sqf b/addons/arsenal/functions/fnc_onMouseButtonUp.sqf index a21d2f04430..1866db5e136 100644 --- a/addons/arsenal/functions/fnc_onMouseButtonUp.sqf +++ b/addons/arsenal/functions/fnc_onMouseButtonUp.sqf @@ -1,6 +1,16 @@ #include "script_component.hpp" /* * Author: commy2 + * Handles mouse button release. + * + * Arguments: + * 0: Not used + * 1: Args + * 1.0: Not used + * 1.1: Mouse button + * + * Return Value: + * None * * Public: No */ diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 56d771dec41..0035308b255 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -7,7 +7,7 @@ * * Arguments: * 0: Left panel control - * 1: Left panel selection + * 1: Left panel selection * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf index a9cdff05bb4..0d742347c92 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLoadouts.sqf @@ -5,8 +5,8 @@ * Handles selection changes on loadouts panel. * * Arguments: - * 0: Loadouts panel control - * 1: Loadouts panel selection + * 0: Arsenal display + * 1: Loadouts panel control * 2: Currently selected loadout's index * * Return Value: diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index 4ddc5250ceb..1f464a917e4 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -6,7 +6,7 @@ * * Arguments: * 0: Right panel control - * 1: Right panel selection + * 1: Right panel selection * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_open3DEN.sqf b/addons/arsenal/functions/fnc_open3DEN.sqf index 03ced7888d4..443f9130fde 100644 --- a/addons/arsenal/functions/fnc_open3DEN.sqf +++ b/addons/arsenal/functions/fnc_open3DEN.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Alganthe - * Replace the 3DEN "edit loadout" menu action + * Replace the 3DEN "edit loadout" menu action. * * Arguments: * None diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf index 2c97f13b920..29416be45e2 100644 --- a/addons/arsenal/functions/fnc_openBox.sqf +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -7,7 +7,7 @@ * Arguments: * 0: Box * 1: Unit to open the arsenal on - * 2: Ignore virtual items and fill arsenal + * 2: Ignore virtual items and fill arsenal (default: false) * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_removeBox.sqf b/addons/arsenal/functions/fnc_removeBox.sqf index 2c89f519e55..2f05cb01114 100644 --- a/addons/arsenal/functions/fnc_removeBox.sqf +++ b/addons/arsenal/functions/fnc_removeBox.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Target - * 1: Remove globally (Optional) + * 1: Remove globally (default: true) * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_removeStat.sqf b/addons/arsenal/functions/fnc_removeStat.sqf index 454aa439c28..585459a9ddb 100644 --- a/addons/arsenal/functions/fnc_removeStat.sqf +++ b/addons/arsenal/functions/fnc_removeStat.sqf @@ -4,7 +4,7 @@ * Remove a stat from ACE Arsenal. * * Arguments: - * 0: Array of IDs + * 0: Array of IDs * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf index 706d483b89b..737419a05bd 100644 --- a/addons/arsenal/functions/fnc_removeVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -6,8 +6,8 @@ * * Arguments: * 0: Target - * 1: Items , - * 2: Add globally (Optional) + * 1: Items + * 2: Remove globally (default: false) * * Return Value: * None diff --git a/addons/arsenal/functions/fnc_sortStatement_amount.sqf b/addons/arsenal/functions/fnc_sortStatement_amount.sqf index afafc5dba69..93a5fff7aeb 100644 --- a/addons/arsenal/functions/fnc_sortStatement_amount.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_amount.sqf @@ -4,8 +4,8 @@ * Statement to sort items by the amount in inventory. * * Arguments: - * 0: Item Config - * 1: Item Name + * 0: Not used + * 1: Not used * 2: Quantity * * Return Value: diff --git a/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf index 155bf2d4746..5fe8c6842e2 100644 --- a/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf +++ b/addons/arsenal/functions/fnc_sortStatement_scopeMag.sqf @@ -7,7 +7,7 @@ * 0: Item Config * * Return Value: - * Sorting Value + * Sorting Value * * Public: No */ diff --git a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf index b4eda44e2f3..22076ae1435 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_accuracy.sqf @@ -4,11 +4,11 @@ * Accuracy bar statement. * * Arguments: - * 0: Stats array + * 0: Not used * 1: Item config path - * 2: Args - * 2.1: Stat limits - * 2.2: Bar limits + * 2: Args + * 2.0: Stat limits + * 2.1: Bar limits * * Return Value: * @@ -16,7 +16,7 @@ * Public: No */ -params ["_stat", "_config", "_args"]; +params ["", "_config", "_args"]; _args params ["_statMinMax", "_barLimits"]; private _dispersion = []; diff --git a/addons/arsenal/functions/fnc_statBarStatement_default.sqf b/addons/arsenal/functions/fnc_statBarStatement_default.sqf index 56f9db9426a..8c547078f69 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_default.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_default.sqf @@ -7,9 +7,9 @@ * 0: Stat * 1: Item config path * 2: Args for configExtreme - * 2.1: Stat limits - * 2.2: Bar limits - * 2.3: Evaluate as a logarithmic number + * 2.0: Stat limits + * 2.1: Bar limits + * 2.2: Evaluate as a logarithmic number * * Return Value: * Bar statement diff --git a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf index f62eb803217..84d82eb4668 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_impact.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_impact.sqf @@ -7,9 +7,9 @@ * Arguments: * 0: Stats array * 1: Item config path - * 2: Args - * 2.1: Stats limits - * 2.2: Bar limits + * 2: Args for configExtreme + * 2.0: Stats limits + * 2.1: Bar limits * * Return Value: * Number diff --git a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf index 21bdde4466a..22d29d7f9b2 100644 --- a/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf +++ b/addons/arsenal/functions/fnc_statBarStatement_rateOfFIre.sqf @@ -6,9 +6,9 @@ * Arguments: * 0: Not used * 1: Item config path - * 2: Args - * 2.1: Stat limits - * 2.2: Bar limits + * 2: Args + * 2.0: Stat limits + * 2.1: Bar limits * * Return Value: * Number diff --git a/addons/arsenal/functions/fnc_updateCamPos.sqf b/addons/arsenal/functions/fnc_updateCamPos.sqf index bab8544fd3d..dc23cbfa3b2 100644 --- a/addons/arsenal/functions/fnc_updateCamPos.sqf +++ b/addons/arsenal/functions/fnc_updateCamPos.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* * Author: Karel Moricky, modified by Alganthe - * Update camera position + * Update camera position. * Modernized a bit, modified vars to fit arsenal rewrite. * * Arguments: From 4597b27d0cdc12ff513d1ebd2951017479a778ec Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 19 May 2023 10:15:16 -0700 Subject: [PATCH 06/24] Fix for defines.hpp Co-authored-by: Dystopian --- addons/arsenal/defines.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 8d8a37ada8f..5f7f34b6933 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -10,7 +10,7 @@ // IDDs #define IDD_MISSION 46 #define IDD_RSCDISPLAYCURATOR 312 -#define IDD_DISPLAY3DEN 313 +#define IDD_DISPLAY3DEN 313 #define IDC_OK 1 // emulate "OK" button #define IDC_CANCEL 2 // emulate "Cancel" button From 4c9eb8b480d2dc32c95f150a8fd040f6cc527af6 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 24 Jun 2023 15:51:41 +0200 Subject: [PATCH 07/24] Moved fnc_baseWeapon, filtered invalid items --- addons/arsenal/XEH_PREP.hpp | 1 + addons/arsenal/XEH_preStart.sqf | 3 + .../arsenal/functions/fnc_addVirtualItems.sqf | 54 +++- .../functions/fnc_baseWeapon.sqf | 6 +- addons/arsenal/functions/fnc_buttonCargo.sqf | 11 +- .../arsenal/functions/fnc_onArsenalOpen.sqf | 12 +- .../functions/fnc_onSelChangedLeft.sqf | 6 +- .../fnc_replaceUniqueItemsLoadout.sqf | 4 +- addons/arsenal/functions/fnc_scanConfig.sqf | 10 +- .../functions/fnc_updateCurrentItemsList.sqf | 2 +- .../arsenal/functions/fnc_verifyLoadout.sqf | 22 +- .../missions/Arsenal.VR/XEH_postInit.sqf | 3 - .../missions/Arsenal.VR/fnc_onPause.sqf | 19 +- .../missions/Arsenal.VR/initPlayerLocal.sqf | 2 +- .../arsenal/missions/Arsenal.VR/mission.sqm | 300 +++++++++--------- addons/common/XEH_PREP.hpp | 1 - addons/common/XEH_preStart.sqf | 3 - addons/common/functions/fnc_addWeapon.sqf | 2 +- docs/wiki/framework/arsenal-framework.md | 4 +- 19 files changed, 234 insertions(+), 231 deletions(-) rename addons/{common => arsenal}/functions/fnc_baseWeapon.sqf (76%) diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 1dc78db024e..84ed1e964df 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -15,6 +15,7 @@ PREP(attributeKeyDown); PREP(attributeLoad); PREP(attributeMode); PREP(attributeSelect); +PREP(baseWeapon); PREP(buttonCargo); PREP(buttonClearAll); PREP(buttonExport); diff --git a/addons/arsenal/XEH_preStart.sqf b/addons/arsenal/XEH_preStart.sqf index ed7f4f0345f..4284d8314ce 100644 --- a/addons/arsenal/XEH_preStart.sqf +++ b/addons/arsenal/XEH_preStart.sqf @@ -2,4 +2,7 @@ #include "XEH_PREP.hpp" +// Cache for FUNC(baseWeapon) +uiNamespace setVariable [QGVAR(baseWeaponNameCache), createHashMap]; + call FUNC(scanConfig); diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index a694b89fdcc..22b5df63b90 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -62,6 +62,7 @@ if (_items isEqualType true) then { private _configItemInfo = ""; private _simulationType = ""; private _hasItemInfo = false; + private _config = configNull; private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; @@ -71,7 +72,8 @@ if (_items isEqualType true) then { private _grenadeList = uiNamespace getVariable [QGVAR(grenadeCache), []]; private _putList = uiNamespace getVariable [QGVAR(putCache), []]; - // _items can contain classNames with scope < 2, which aren't necessarily in the arsenal cache + // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration + // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 { _configItemInfo = _cfgWeapons >> _x >> "ItemInfo"; _simulationType = getText (_cfgWeapons >> _x >> "simulation"); @@ -79,6 +81,13 @@ if (_items isEqualType true) then { switch (true) do { case (isClass (_cfgWeapons >> _x)): { + _config = _cfgWeapons >> _x; + + // Check if valid class + if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + continue; + }; + switch (true) do { // Weapon attachments case ( @@ -129,7 +138,7 @@ if (_items isEqualType true) then { // Binoculars case ( _simulationType == "Binocular" || - {_simulationType == "Weapon" && {getNumber (_cfgWeapons >> _x >> "type") == TYPE_BINOCULAR_AND_NVG}} + {_simulationType == "Weapon" && {getNumber (_config >> "type") == TYPE_BINOCULAR_AND_NVG}} ): { (_cargo select IDX_VIRT_BINO) pushBackUnique _x; }; @@ -159,18 +168,18 @@ if (_items isEqualType true) then { }; // Weapons, at the bottom to avoid adding binos case ( - isClass (_cfgWeapons >> _x >> "WeaponSlotsInfo") && - {getNumber (_cfgWeapons >> _x >> "type") != TYPE_BINOCULAR_AND_NVG} + isClass (_config >> "WeaponSlotsInfo") && + {getNumber (_config >> "type") != TYPE_BINOCULAR_AND_NVG} ): { - switch (getNumber (_cfgWeapons >> _x >> "type")) do { + switch (getNumber (_config >> "type")) do { case TYPE_WEAPON_PRIMARY: { - ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_x call EFUNC(common,baseWeapon)); + ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_x call FUNC(baseWeapon)); }; case TYPE_WEAPON_HANDGUN: { - ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_x call EFUNC(common,baseWeapon)); + ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_x call FUNC(baseWeapon)); }; case TYPE_WEAPON_SECONDARY: { - ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_x call EFUNC(common,baseWeapon)); + ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_x call FUNC(baseWeapon)); }; }; }; @@ -180,13 +189,20 @@ if (_items isEqualType true) then { {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && {_x isKindOf ["CBA_MiscItem", _cfgWeapons]}} || {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} + {getText (_config >> "simulation") == "ItemMineDetector"} ): { (_cargo select IDX_VIRT_MISC_ITEMS) pushBackUnique _x; }; }; }; case (isClass (_cfgMagazines >> _x)): { + _config = _cfgMagazines >> _x; + + // Check if valid class + if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + continue; + }; + // Check what type the magazine actually is switch (true) do { // Grenades @@ -199,8 +215,8 @@ if (_items isEqualType true) then { }; // Primary, handgun & secondary weapon magazines, and magazines that are forced with "ace_arsenal_hide = -1" case ( - getNumber (_cfgMagazines >> _x >> QGVAR(hide)) == -1 || - {getNumber (_cfgMagazines >> _x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL]} + getNumber (_config >> QGVAR(hide)) == -1 || + {getNumber (_config >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL]} ): { (_cargo select IDX_VIRT_ITEMS_ALL) pushBackUnique _x; }; @@ -208,12 +224,26 @@ if (_items isEqualType true) then { }; // Backpacks case (isClass (_cfgVehicles >> _x)): { - if (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1) then { + _config = _cfgVehicles >> _x; + + // Check if valid class + if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + continue; + }; + + if (getNumber (_config >> "isBackpack") == 1) then { (_cargo select IDX_VIRT_BACKPACK) pushBackUnique _x; }; }; // Goggles case (isClass (_cfgGlasses >> _x)): { + _config = _cfgGlasses >> _x; + + // Check if valid class + if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + continue; + }; + (_cargo select IDX_VIRT_GOGGLES) pushBackUnique _x; }; }; diff --git a/addons/common/functions/fnc_baseWeapon.sqf b/addons/arsenal/functions/fnc_baseWeapon.sqf similarity index 76% rename from addons/common/functions/fnc_baseWeapon.sqf rename to addons/arsenal/functions/fnc_baseWeapon.sqf index a00ee086d0a..67ab03f11e1 100644 --- a/addons/common/functions/fnc_baseWeapon.sqf +++ b/addons/arsenal/functions/fnc_baseWeapon.sqf @@ -11,7 +11,7 @@ * None * * Example: - * ["arifle_AK12_GL_lush_arco_pointer_F"] call ace_common_fnc_baseWeapon + * ["arifle_AK12_GL_lush_arco_pointer_F"] call ace_arsenal_fnc_baseWeapon * * Public: Yes */ @@ -48,7 +48,9 @@ if (isClass _configBase) exitWith { scopeName "main"; // Only take weapons available to the arsenal -while {isClass _config && {getNumber (_config >> "scope") == 2}} do { +// https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration +// https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 +while {isClass _config && {if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2} else {getNumber (_config >> "scope") > 0}} && {getNumber (_config >> QGVAR(hide)) != 1}} do { if (count (_config >> "LinkedItems") == 0) exitWith { _className = configName _config; (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _className]; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index d10cf8da926..170621d2f41 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -16,13 +16,13 @@ params ["_display", "_addOrRemove"]; -_addOrRemove = _addOrRemove > 0; +private _add = _addOrRemove > 0; private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; private _lnbCurSel = lnbCurSelRow _ctrlList; // If item is unique, don't allow adding more -if (_addOrRemove && {(_ctrlList lnbValue [_lnbCurSel, 2]) == 1}) exitWith {}; +if (_add && {(_ctrlList lnbValue [_lnbCurSel, 2]) == 1}) exitWith {}; private _containerItems = []; private _item = _ctrlList lnbData [_lnbCurSel, 0]; @@ -31,7 +31,7 @@ private _item = _ctrlList lnbData [_lnbCurSel, 0]; private _container = switch (GVAR(currentLeftPanel)) do { // Uniform case IDC_buttonUniform: { - if (_addOrRemove) then { + if (_add) then { for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { GVAR(center) addItemToUniform _item; }; @@ -53,7 +53,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; // Vest case IDC_buttonVest: { - if (_addOrRemove) then { + if (_add) then { for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { GVAR(center) addItemToVest _item; }; @@ -75,7 +75,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; // Backpack case IDC_buttonBackpack: { - if (_addOrRemove) then { + if (_add) then { for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { GVAR(center) addItemToBackpack _item; }; @@ -100,7 +100,6 @@ private _container = switch (GVAR(currentLeftPanel)) do { // Find out how many items of that type there are and update the number displayed _ctrlList lnbSetText [[_lnbCurSel, 2], str ({_x == _item} count _containerItems)]; -//////////////////// Return NUMBER, as it did before or return BOOL, as the doc says is should ? [QGVAR(cargoChanged), [_display, _item, _addOrRemove, GVAR(shiftState)]] call CBA_fnc_localEvent; // Refresh availibility of items based on space remaining in container diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index ce717e22cd1..51c40b5d2ec 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -70,7 +70,7 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; // Add weapon if (_weapon != "") then { - _weapon = _weapon call EFUNC(common,baseWeapon); + _weapon = _weapon call FUNC(baseWeapon); if (_weapon != "") then { // If bino, add it in a different place than regular weapons @@ -151,16 +151,6 @@ call FUNC(updateCurrentItemsList); // This takes care of items that aren't available in the arsenal (either wrong tab or arsenal doesn't have it whitelisted) call FUNC(updateUniqueItemsList); -// Get the type of the current weapon -private _currentWeapon = currentWeapon GVAR(center); - -GVAR(currentWeaponType) = switch (true) do { - case (_currentWeapon == (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON)): {0}; - case (_currentWeapon == (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON)): {1}; - case (_currentWeapon == (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON)): {2}; - default {-1}; -}; - [QGVAR(displayOpened), [_display]] call CBA_fnc_localEvent; //--------------- Fade out unused elements diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 0035308b255..e6d2c605c92 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -51,7 +51,7 @@ private _fnc_clearPreviousWepMags = { switch (GVAR(currentLeftPanel)) do { // Primary weapon case IDC_buttonPrimaryWeapon: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) call EFUNC(common,baseWeapon); + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) call FUNC(baseWeapon); // If nothing selected, remove primary weapon and its magazines if (_item == "") then { @@ -119,7 +119,7 @@ switch (GVAR(currentLeftPanel)) do { }; // Handgun weapon case IDC_buttonHandgun: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) call EFUNC(common,baseWeapon); + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) call FUNC(baseWeapon); // If nothing selected, remove handgun weapon and its magazines if (_item == "") then { @@ -188,7 +188,7 @@ switch (GVAR(currentLeftPanel)) do { }; // Secondary weapon case IDC_buttonSecondaryWeapon: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) call EFUNC(common,baseWeapon); + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) call FUNC(baseWeapon); // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf index 50a06997546..0ce36717c8c 100644 --- a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -42,7 +42,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; // Find baseweapon of weapon if (_weapon != "") then { - _x set [0, _weapon call EFUNC(common,baseWeapon)]; + _x set [0, _weapon call FUNC(baseWeapon)]; }; }; // Uniform, vest, backpack @@ -73,7 +73,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; _weapon = (_x select 0) select 0; if (_weapon != "") then { - (_x select 0) set [0, _weapon call EFUNC(common,baseWeapon)]; + (_x select 0) set [0, _weapon call FUNC(baseWeapon)]; }; }; // Magazines have 3 entries: Name, amount and ammo count diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index cbc00fd98ac..6ab9387cf9a 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -15,8 +15,10 @@ private _configItems = EMPTY_VIRTUAL_ARSENAL; +// https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration +// https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 private _filterFunction = [{ - isClass _x && {(if (isNumber (_x >> 'scopeArsenal')) then {getNumber (_x >> 'scopeArsenal')} else {getNumber (_x >> 'scope')}) == 2} && {getNumber (_x >> 'ace_arsenal_hide') != 1} + isClass _x && {(if (isNumber (_x >> "scopeArsenal")) then {getNumber (_x >> "scopeArsenal")} else {getNumber (_x >> "scope")}) == 2} && {getNumber (_x >> QGVAR(hide)) != 1} }] call EFUNC(common,codeToString); private _cfgWeapons = configFile >> "CfgWeapons"; @@ -100,13 +102,13 @@ private _isMiscItem = false; ): { switch (getNumber (_x >> "type")) do { case TYPE_WEAPON_PRIMARY: { - ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); + ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_className call FUNC(baseWeapon)); }; case TYPE_WEAPON_HANDGUN: { - ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); + ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_className call FUNC(baseWeapon)); }; case TYPE_WEAPON_SECONDARY: { - ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_className call EFUNC(common,baseWeapon)); + ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_className call FUNC(baseWeapon)); }; }; }; diff --git a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf index 97b3f968bad..3e0a0646f18 100644 --- a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf @@ -28,7 +28,7 @@ private _indexCurrentItems = -1; case IDX_LOADOUT_BINO: { _x params [["_weapon", ""], ["_muzzle", ""], ["_flashlight", ""], ["_optics", ""], ["_primaryMagazine", []], ["_secondaryMagazine", []], ["_bipod", ""]]; - _weapon = _weapon call EFUNC(common,baseWeapon); + _weapon = _weapon call FUNC(baseWeapon); _isWeapon = _forEachIndex != IDX_LOADOUT_BINO; // If bino, add it in a different place than regular weapons diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index d4c4164efef..b8cd915fa0a 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -204,27 +204,7 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do {isClass (_cfgVehicles >> _item)} ) then { // Check if item is available in arsenal - if !( - ////////////////// use _item in GVAR(virtualItemsFlat) ? - _item in (_accsArray select IDX_VIRT_OPTICS_ATTACHMENTS) || - {_item in (_accsArray select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || - {_item in (_accsArray select IDX_VIRT_MUZZLE_ATTACHMENTS)} || - {_item in (_accsArray select IDX_VIRT_BIPOD_ATTACHMENTS)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_HEADGEAR)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_UNIFORM)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_VEST)} ||\ - {_item in (GVAR(virtualItems) select IDX_VIRT_BACKPACK)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_GOGGLES)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_NVG)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_MAP)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_COMPASS)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_RADIO)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_WATCH)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_COMMS)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_GRENADES)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS)} - ) then { + if !(_item in GVAR(virtualItemsFlat)) then { _unavailableItemsList pushBackUnique _item; ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; INC(_unavailableItemsAmount); diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf index 68b193bb3de..c5fabdbb8a2 100644 --- a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -88,16 +88,13 @@ cba_diagnostic_projectileMaxLines = 10; { _unit = _x; - removeVest _unit; _unit addVest vest _player; removeBackpack _unit; _unit addBackpack backpack _player; - removeHeadgear _unit; _unit addHeadgear headgear _player; - removeGoggles _unit; _unit addGoggles goggles _player; removeAllWeapons _unit; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf index 8541cd840e7..f7536cae67a 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_onPause.sqf @@ -1,5 +1,5 @@ #include "script_component.hpp" -#include "..\..\defines.hpp" +#include "\z\ace\addons\arsenal\defines.hpp" /* * Author: commy2 * @@ -14,15 +14,18 @@ _ctrlButtonAbort ctrlSetText LLSTRING(Mission); _ctrlButtonAbort ctrlSetTooltip LLSTRING(ReturnToArsenal); _ctrlButtonAbort ctrlSetEventHandler ["ButtonClick", { - params ["_control"]; + // Don't open arsenal unless it's the player, on foot + if (player == call CBA_fnc_currentUnit && {isNull objectParent player}) then { + params ["_control"]; - // Close pause menu - (ctrlParent _control) closeDisplay IDC_CANCEL; + // Close pause menu + (ctrlParent _control) closeDisplay IDC_CANCEL; - // Open the arsenal again - { - [player, player, true] call FUNC(openBox); - } call CBA_fnc_execNextFrame; + // Open the arsenal again + { + [player, player, true] call FUNC(openBox); + } call CBA_fnc_execNextFrame; + }; true } call EFUNC(common,codeToString)]; diff --git a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf index 324ac7c6180..28e19bba478 100644 --- a/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf +++ b/addons/arsenal/missions/Arsenal.VR/initPlayerLocal.sqf @@ -1,5 +1,5 @@ #include "script_component.hpp" -#include "..\..\defines.hpp" +#include "\z\ace\addons\arsenal\defines.hpp" params ["_unit"]; diff --git a/addons/arsenal/missions/Arsenal.VR/mission.sqm b/addons/arsenal/missions/Arsenal.VR/mission.sqm index c43d901f6ec..b23f61c1bf1 100644 --- a/addons/arsenal/missions/Arsenal.VR/mission.sqm +++ b/addons/arsenal/missions/Arsenal.VR/mission.sqm @@ -1,163 +1,163 @@ version=12; class Mission { - addOns[]= - { - "A3_Map_VR", - "A3_Characters_F_BLUFOR", - "a3_characters_f_beta", - "a3_characters_f" - }; - addOnsAuto[]= - { - "A3_Characters_F_BLUFOR", - "a3_characters_f", - "A3_Map_VR" - }; - randomSeed=5486937; - class Intel - { - briefingName="@STR_A3_Arsenal"; - startWeather=0; - startWind=0.099999994; - startWaves=0.099999994; - forecastWeather=0; - forecastWind=0.099999994; - forecastWaves=0.099999994; - forecastLightnings=0.099999994; - year=2035; - month=2; - day=24; - hour=12; - minute=0; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; - class Groups - { - items=1; - class Item0 - { - side="CIV"; - class Vehicles - { - items=1; - class Item0 - { - position[]={4256,5,4192}; - azimut=180; - id=0; - side="CIV"; - vehicle="C_man_1"; - player="PLAYER COMMANDER"; - leader=1; - skill=0.60000002; - }; - }; - }; - }; - class Sensors - { - items=1; - class Item0 - { - position[]={4271.2827,5,4170.251}; - a=0; - b=0; - interruptable=1; - age="UNKNOWN"; - expCond="cheat1"; - expActiv="endmission ""end1"""; - class Effects - { - }; - }; - }; + addOns[]= + { + "A3_Map_VR", + "A3_Characters_F_BLUFOR", + "a3_characters_f_beta", + "a3_characters_f" + }; + addOnsAuto[]= + { + "A3_Characters_F_BLUFOR", + "a3_characters_f", + "A3_Map_VR" + }; + randomSeed=5486937; + class Intel + { + briefingName="@STR_A3_Arsenal"; + startWeather=0; + startWind=0.099999994; + startWaves=0.099999994; + forecastWeather=0; + forecastWind=0.099999994; + forecastWaves=0.099999994; + forecastLightnings=0.099999994; + year=2035; + month=2; + day=24; + hour=12; + minute=0; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; + class Groups + { + items=1; + class Item0 + { + side="CIV"; + class Vehicles + { + items=1; + class Item0 + { + position[]={4256,5,4192}; + azimut=180; + id=0; + side="CIV"; + vehicle="C_man_1"; + player="PLAYER COMMANDER"; + leader=1; + skill=0.60000002; + }; + }; + }; + }; + class Sensors + { + items=1; + class Item0 + { + position[]={4271.2827,5,4170.251}; + a=0; + b=0; + interruptable=1; + age="UNKNOWN"; + expCond="cheat1"; + expActiv="endmission ""end1"""; + class Effects + { + }; + }; + }; }; class Intro { - addOns[]= - { - "A3_Map_VR" - }; - addOnsAuto[]= - { - "A3_Map_VR" - }; - randomSeed=12455686; - class Intel - { - timeOfChanges=1800.0002; - startWeather=0; - startWind=0.1; - startWaves=0.1; - forecastWeather=0; - forecastWind=0.1; - forecastWaves=0.1; - forecastLightnings=0.1; - year=2035; - day=28; - hour=13; - minute=37; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=12455686; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; }; class OutroWin { - addOns[]= - { - "A3_Map_VR" - }; - addOnsAuto[]= - { - "A3_Map_VR" - }; - randomSeed=9312504; - class Intel - { - timeOfChanges=1800.0002; - startWeather=0; - startWind=0.1; - startWaves=0.1; - forecastWeather=0; - forecastWind=0.1; - forecastWaves=0.1; - forecastLightnings=0.1; - year=2035; - day=28; - hour=13; - minute=37; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=9312504; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; }; class OutroLoose { - addOns[]= - { - "A3_Map_VR" - }; - addOnsAuto[]= - { - "A3_Map_VR" - }; - randomSeed=15192082; - class Intel - { - timeOfChanges=1800.0002; - startWeather=0; - startWind=0.1; - startWaves=0.1; - forecastWeather=0; - forecastWind=0.1; - forecastWaves=0.1; - forecastLightnings=0.1; - year=2035; - day=28; - hour=13; - minute=37; - startFogDecay=0.0049999999; - forecastFogDecay=0.0049999999; - }; + addOns[]= + { + "A3_Map_VR" + }; + addOnsAuto[]= + { + "A3_Map_VR" + }; + randomSeed=15192082; + class Intel + { + timeOfChanges=1800.0002; + startWeather=0; + startWind=0.1; + startWaves=0.1; + forecastWeather=0; + forecastWind=0.1; + forecastWaves=0.1; + forecastLightnings=0.1; + year=2035; + day=28; + hour=13; + minute=37; + startFogDecay=0.0049999999; + forecastFogDecay=0.0049999999; + }; }; diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 178aa4d387f..b116548c125 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -18,7 +18,6 @@ PREP(ambientBrightness); PREP(arithmeticGetResult); PREP(arithmeticSetSource); PREP(ASLToPosition); -PREP(baseWeapon); PREP(binarizeNumber); PREP(blurScreen); PREP(cachedCall); diff --git a/addons/common/XEH_preStart.sqf b/addons/common/XEH_preStart.sqf index d2238395fe6..b872756af8d 100644 --- a/addons/common/XEH_preStart.sqf +++ b/addons/common/XEH_preStart.sqf @@ -13,8 +13,5 @@ if (isFilePatchingEnabled) then { // Cache for FUNC(getAddon) uiNamespace setVariable [QGVAR(addonCache), createHashMap]; -// Cache for FUNC(baseWeapon) -uiNamespace setVariable [QGVAR(baseWeaponNameCache), createHashMap]; - // Cache for FUNC(getConfigName) uiNamespace setVariable [QGVAR(configNames), createHashMap]; diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf index 46536b753ec..f00cad8d090 100644 --- a/addons/common/functions/fnc_addWeapon.sqf +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -2,7 +2,7 @@ /* * Author: commy2, johnb43 * Adds weapon to unit without taking a magazine. - * Same as CBA_fnc_addWeaponWithoutItems, but with some small modifications. + * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items. * * Arguments: * 0: Unit to add the weapon to diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 6bf8b301bd5..ee580e255ad 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -134,7 +134,7 @@ Examples: ACE Arsenal has 2 new config entries for items: -- `ace_arsenal_hide`: `0`(shown) or `1` (hidden), used to hide items from ACE Arsenal or `-1` (forced show), for vehicle magazines. +- `ace_arsenal_hide`: `0`(shown) or `1` (hidden), used to hide items from ACE Arsenal or `-1` (forced show), for magazines. - `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout. Supports configs in "CfgWeapons", "CfgMagazines" and "CfgVehicles". Item that replaces must be of the same config type as the original item. Both of them are optional. @@ -367,7 +367,7 @@ All are local. | ace_arsenal_onLoadoutDelete | loadout name (STRING) | | ace_arsenal_loadoutShared | Loadouts list listnBox control (CONTROL), [loadout author (STRING), loadout name (STRING), loadout data (ARRAY)] | | ace_arsenal_loadoutUnshared | Loadouts list listnBox control (CONTROL), loadout author (STRING), loadout name (STRING) | -| ace_arsenal_cargoChanged | Arsenal display (DISPLAY), item (STRING), add or remove (BOOL), shiftState (BOOL) | +| ace_arsenal_cargoChanged | Arsenal display (DISPLAY), item (STRING), add or remove (NUMBER), shiftState (BOOL) | | ace_arsenal_loadoutImported | Arsenal display (DISPLAY), (import list (BOOL) | | ace_arsenal_loadoutExported | Arsenal display (DISPLAY), export list (BOOL) | | ace_arsenal_loadoutsDisplayOpened | loadouts screen display (DISPLAY) | 3.12.3 | From ca063f49ff2df94471fe2f64157daac96075c96b Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 24 Jun 2023 11:25:11 -0700 Subject: [PATCH 08/24] Update addons/arsenal/functions/fnc_scanConfig.sqf Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/arsenal/functions/fnc_scanConfig.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 6ab9387cf9a..26ec84fde90 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -17,9 +17,9 @@ private _configItems = EMPTY_VIRTUAL_ARSENAL; // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 -private _filterFunction = [{ +private _filterFunction = toString { isClass _x && {(if (isNumber (_x >> "scopeArsenal")) then {getNumber (_x >> "scopeArsenal")} else {getNumber (_x >> "scope")}) == 2} && {getNumber (_x >> QGVAR(hide)) != 1} -}] call EFUNC(common,codeToString); +}; private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; From f329fe1aab27f75ba7dbad7a716ebcfd8627b368 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 25 Jun 2023 13:50:47 +0200 Subject: [PATCH 09/24] Fixes and tweaks - Sorting is guaranteed to give a fixed order - Dog tags no longer throw errors when reloading the ACE arsenal mission when you had some saved in your loadout before quitting the last time you played. --- .../arsenal/functions/fnc_addListBoxItem.sqf | 29 ++----- addons/arsenal/functions/fnc_baseWeapon.sqf | 2 +- .../arsenal/functions/fnc_fillRightPanel.sqf | 26 +++--- .../functions/fnc_onSelChangedLeft.sqf | 2 +- addons/arsenal/functions/fnc_scanConfig.sqf | 5 +- addons/arsenal/functions/fnc_sortPanel.sqf | 82 ++++++++++++++----- addons/dogtags/XEH_postInit.sqf | 31 ++++--- 7 files changed, 96 insertions(+), 81 deletions(-) diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index 3aee41b8e0c..d0274c21ae5 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -20,34 +20,15 @@ params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]]; -// Sanitise, as it's public -private _itemInfo = toLower (_configCategory + _className); -private _cachedItemInfo = GVAR(addListBoxItemCache) getOrDefault [_itemInfo, []]; - -// If not in cache, find info and cache it for later use -if (_cachedItemInfo isEqualTo []) then { +// Sanitise key, as it's public; If not in cache, find info and cache it for later use +private _cachedItemInfo = GVAR(addListBoxItemCache) getOrDefaultCall [toLower (_configCategory + _className), { // Get classname (config case), display name, picture and DLC private _configPath = configFile >> _configCategory >> _className; - - _cachedItemInfo set [0, configName _configPath]; - _cachedItemInfo set [1, getText (_configPath >> "displayName")]; - - // If _pictureEntryName is empty, then this item has no picture (e.g. faces) - _cachedItemInfo set [2, if (_pictureEntryName == "") then {""} else {getText (_configPath >> _pictureEntryName)}]; - - // Get name of DLC private _dlcName = _configPath call EFUNC(common,getAddon); - // Mod picture - if (_dlcName != "") then { - _cachedItemInfo set [3, (modParams [_dlcName, ["logo"]]) param [0, ""]]; - } else { - _cachedItemInfo set [3, ""]; - }; - - // Store in cache - GVAR(addListBoxItemCache) set [_itemInfo, _cachedItemInfo]; -}; + // If _pictureEntryName is empty, then this item has no picture (e.g. faces) + [configName _configPath, getText (_configPath >> "displayName"), if (_pictureEntryName == "") then {""} else {getText (_configPath >> _pictureEntryName)}, if (_dlcName != "") then {(modParams [_dlcName, ["logo"]]) param [0, ""]} else {""}] +}, true]; _cachedItemInfo params ["_className", "_displayName", "_itemPicture", "_modPicture"]; diff --git a/addons/arsenal/functions/fnc_baseWeapon.sqf b/addons/arsenal/functions/fnc_baseWeapon.sqf index 67ab03f11e1..6d8fb4f72e3 100644 --- a/addons/arsenal/functions/fnc_baseWeapon.sqf +++ b/addons/arsenal/functions/fnc_baseWeapon.sqf @@ -8,7 +8,7 @@ * 0: Weapon * * Return Value: - * None + * Base weapon * * Example: * ["arifle_AK12_GL_lush_arco_pointer_F"] call ace_arsenal_fnc_baseWeapon diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index e4cd1a96b44..d6a74421b13 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -42,24 +42,18 @@ if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { private _fnc_fill_right_Container = { params ["_configCategory", "_className", "_isMagazine", ["_isUnique", false, [false]]]; - // If items is not in the arsenal, it must be unique - if !(_className in GVAR(virtualItemsFlat)) then { + // If item is not in the arsenal, it must be unique + if (!_isUnique && {!(_className in GVAR(virtualItemsFlat))}) then { _isUnique = true; }; - private _cachedItemInfo = GVAR(rightPanelCache) getOrDefault [_configCategory + _className, []]; - // If not in cache, find info and cache it for later use - if (_cachedItemInfo isEqualTo []) then { + private _cachedItemInfo = GVAR(rightPanelCache) getOrDefaultCall [_configCategory + _className, { // Get display name, picture and mass private _configPath = configFile >> _configCategory >> _className; - _cachedItemInfo set [0, getText (_configPath >> "displayName")]; - _cachedItemInfo set [1, getText (_configPath >> "picture")]; - _cachedItemInfo set [2, if (_isMagazine) then {getNumber (_configPath >> "mass")} else {getNumber (_configPath >> "itemInfo" >> "mass")}]; - - GVAR(rightPanelCache) set [_configCategory + _className, _cachedItemInfo] - }; + [getText (_configPath >> "displayName"), getText (_configPath >> "picture"), if (_isMagazine) then {getNumber (_configPath >> "mass")} else {getNumber (_configPath >> "itemInfo" >> "mass")}] + }, true]; _cachedItemInfo params ["_displayName", "_picture", "_mass"]; @@ -69,7 +63,7 @@ private _fnc_fill_right_Container = { _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select _isUnique]; - _ctrlPanel lbSetTooltip [_lbAdd * (count lnbGetColumnsPosition _ctrlPanel), format ["%1\n%2", _displayName, _className]]; + _ctrlPanel lnbSetTooltip [[_lbAdd, 0], format ["%1\n%2", _displayName, _className]]; _ctrlPanel setVariable [_className, _mass]; }; @@ -118,28 +112,28 @@ switch (GVAR(currentLeftPanel)) do { case IDC_buttonPrimaryWeapon: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 0 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 0 select 1; - _compatibleItems = compatibleItems (_weapons select 0)/* call CBA_fnc_compatibleItems*/; + _compatibleItems = compatibleItems (_weapons select 0); _itemsToCheck = GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS; }; // Handgun weapon case IDC_buttonHandgun: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 1 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 1 select 1; - _compatibleItems = (_weapons select 1) call CBA_fnc_compatibleItems; + _compatibleItems = compatibleItems (_weapons select 1); _itemsToCheck = GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS; }; // Secondary weapon case IDC_buttonSecondaryWeapon: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 2 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 2 select 1; - _compatibleItems = (_weapons select 2) call CBA_fnc_compatibleItems; + _compatibleItems = compatibleItems (_weapons select 2); _itemsToCheck = GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS; }; // Binoculars case IDC_buttonBinoculars: { _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 3 select 0; _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 3 select 1; - _compatibleItems = (_weapons select 3) call CBA_fnc_compatibleItems; + _compatibleItems = compatibleItems (_weapons select 3); _itemsToCheck = GVAR(currentItems) select IDX_CURR_BINO_ITEMS; }; // Uniform, vest or backpack diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index e6d2c605c92..7dff2878697 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -434,7 +434,7 @@ switch (GVAR(currentLeftPanel)) do { }; // Binoculars case IDC_buttonBinoculars: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_BINO) call EFUNC(common,baseWeapon); + private _baseWeapon = (GVAR(currentItems) select IDX_CURR_BINO) call FUNC(baseWeapon); // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 26ec84fde90..ae31436709e 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -186,8 +186,11 @@ _putList = _putList - [""]; private _faceCache = createHashMap; private _dlcName = ""; private _modPicture = ""; +private _faceCategory = ""; { + _faceCategory = configName _x; + { if (getNumber (_x >> "disabled") == 0 && {getText (_x >> "head") != ""} && {configName _x != "Default"}) then { _dlcName = _x call EFUNC(common,getAddon); @@ -198,7 +201,7 @@ private _modPicture = ""; _modPicture = (modParams [_dlcName, ["logo"]]) param [0, ""]; }; - _faceCache set [configName _x, [getText (_x >> "displayName"), _modPicture]]; + _faceCache set [configName _x, [getText (_x >> "displayName"), _modPicture, _faceCategory]]; }; } forEach ("true" configClasses _x); } forEach ("true" configClasses (configfile >> "CfgFaces")); diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index dc6d0536870..ec40beb1c81 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, Dedmen, Brett Mayson - * Sort arsenal panel. + * Author: Alganthe, Dedmen, Brett Mayson, johnb43 + * Sort an arsenal panel. * * Arguments: * 0: Sort control @@ -19,6 +19,9 @@ private _display = ctrlParent _sortControl; private _rightSort = ctrlIDC _sortControl == IDC_sortRightTab; private _right = _rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}; +private _cfgFaces = configFile >> "CfgFaces"; +private _cfgUnitInsignia = configFile >> "CfgUnitInsignia"; +private _cfgUnitInsigniaMission = missionConfigFile >> "CfgUnitInsignia"; if (_rightSort) then { [ @@ -58,9 +61,9 @@ if (_rightSort) then { switch (GVAR(currentLeftPanel)) do { case IDC_buttonBackpack: {configFile >> "CfgVehicles"}; case IDC_buttonGoggles: {configFile >> "CfgGlasses"}; - case IDC_buttonFace: {configFile >> "CfgFaces" >> "Man_A3"}; + case IDC_buttonFace: {_cfgFaces}; case IDC_buttonVoice: {configFile >> "CfgVoice"}; - case IDC_buttonInsignia: {configFile >> "CfgUnitInsignia"}; + case IDC_buttonInsignia: {_cfgUnitInsignia}; default {configFile >> "CfgWeapons"}; }, (GVAR(sortListLeftPanel) select ([ @@ -117,7 +120,18 @@ private _quantity = ""; private _itemCfg = configNull; private _value = ""; private _name = ""; -private _data = ""; + +private _faceCache = if (_cfgClass == _cfgFaces) then { + uiNamespace getVariable [QGVAR(faceCache), createHashMap] +} else { + createHashMap +}; + +private _countColumns = if (_right) then { + count lnbGetColumnsPosition _panel +} else { + 0 +}; private _for = if (_right) then { for '_i' from 0 to (lnbSize _panel select 0) - 1 @@ -140,7 +154,24 @@ _for do { 0 }; - _itemCfg = _cfgClass >> _item; + // Check item's config + _itemCfg = if !(_cfgClass in [_cfgFaces, _cfgUnitInsignia]) then { + _cfgClass >> _item + } else { + // If insignia, check both config and mission file + if (_cfgClass == _cfgUnitInsignia) then { + _itemCfg = _cfgClass >> _item; + + if (isNull _itemCfg) then { + _itemCfg = _cfgUnitInsigniaMission >> _item; + }; + + _itemCfg + } else { + // If face, check correct category + _cfgClass >> (_faceCache get _item) param [2, "Man_A3"] >> _item + }; + }; // Some items may not belong to the config class for the panel (misc. items panel can have unique items) if (isNull _itemCfg) then { @@ -162,16 +193,16 @@ _for do { // Save the current row's item's name in a cache and set text to it's sorting value if (_right) then { - _name = _panel lnbText [_i, 1]; - _originalNames set [_item, _name]; + _originalNames set [_item, _panel lnbText [_i, 1]]; - _panel lnbSetText [[_i, 1], format ["%1%2", _value, _name]]; + // Use tooltip to sort, as it also contains the classname, which means a fixed alphabetical order is guaranteed + _panel lnbSetText [[_i, 1], format ["%1%2", _value, _panel lbTooltip (_i * _countColumns)]]; } else { if (_item != "") then { - _name = _panel lbText _i; - _originalNames set [_item, _name]; + _originalNames set [_item, _panel lbText _i]; - _panel lbSetText [_i, format ["%1%2", _value, _name]]; + // Use tooltip to sort, as it also contains the classname, which means a fixed alphabetical order is guaranteed + _panel lbSetText [_i, format ["%1%2", _value, _panel lbTooltip _i]]; }; }; }; @@ -181,26 +212,35 @@ if (_right) then { _panel lnbSort [1, false]; _for do { - _data = _panel lnbData [_i, 0]; + _item = _panel lnbData [_i, 0]; + + _panel lnbSetText [[_i, 1], _originalNames get _item]; - if (_curSel != -1 && {_data == _selected}) then { + // Set selection after text, otherwise item info box on the right side shows invalid name + if (_curSel != -1 && {_item == _selected}) then { _panel lnbSetCurSelRow _i; - }; - _panel lnbSetText [[_i, 1], _originalNames get _data]; + // To avoid unnecessary checks after previsouly selected item was found + _curSel = -1; + }; }; } else { lbSort [_panel, "ASC"]; _for do { - _data = _panel lbData _i; + _item = _panel lbData _i; - if (_curSel != -1 && {_data == _selected}) then { - _panel lbSetCurSel _i; + // Check if valid item (problems can be caused when searching) + if (_item != "") then { + _panel lbSetText [_i, _originalNames get _item]; }; - if (_data != "") then { - _panel lbSetText [_i, _originalNames get _data]; + // Set selection after text, otherwise item info box on the right side shows invalid name + if (_curSel != -1 && {_item == _selected}) then { + _panel lbSetCurSel _i; + + // To avoid unnecessary checks after previsouly selected item was found + _curSel = -1; }; }; }; diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index 02d2db862b9..d7476345c95 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -5,8 +5,7 @@ [QGVAR(getDogtagItem), DFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; [QGVAR(addDogtagItem), DFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; - -//Add actions and event handlers only if ace_medical is loaded +// Add actions and event handlers only if ace_medical is loaded // - Adding actions via config would create a dependency if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (hasInterface) then { @@ -46,35 +45,33 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { }; }; +// If the arsenal is loaded, show the custom names for dog tags when in the arsenal if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { [QEGVAR(arsenal,rightPanelFilled), { - params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then { LOG("passed"); private _rightPanel = _display displayCtrl 15; - (lnbSize _rightPanel) params ["_rows", "_columns"]; - - private _allDogtags = missionNameSpace getVariable [QGVAR(allDogtags), []]; - private _allDogtagDatas = missionNameSpace getVariable [QGVAR(allDogtagDatas), []]; - - for "_r" from 0 to (_rows - 1) do { - private _data = _rightPanel lnbData [_r, 0]; + private _allDogtags = missionNamespace getVariable [QGVAR(allDogtags), []]; + private _allDogtagsData = missionNamespace getVariable [QGVAR(allDogtagDatas), []]; + private _cfgWeapons = configFile >> "CfgWeapons"; + private _item = ""; + private _dogtagData = []; - if (_data isKindOf ["ACE_dogtag", (configFile >> "CfgWeapons")]) then { + for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { + _item = _rightPanel lnbData [_i, 0]; - private _dogtagData = []; - private _index = _allDogtags find _data; - _dogtagData = _allDogtagDatas select _index; - private _dogtagString = [localize LSTRING(itemName), ": ", (_dogtagData select 0)] joinString ""; + if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { + _dogtagData = _allDogtagsData param [_allDogtags find _item, []]; - _rightPanel lnbSetText [[_r, 1], _dogtagString]; + // If data doesn't exist, put name as "unknown" + _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _dogtagData param [0, LELSTRING(common,unknown)]] joinString ""]; }; }; }; }] call CBA_fnc_addEventHandler; }; -// disable dogtags for civilians +// Disable dogtags for civilians "CIV_F" call FUNC(disableFactionDogtags); From 6d8549d4b2292ca41f1efd4cf934a3c4b9d69c0a Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 1 Jul 2023 10:30:41 +0200 Subject: [PATCH 10/24] Cleanup, bug fixes and additions - Added the ability to add items from "CfgMagazines" into the "Misc. items" or custom tabs. - Added "baseWeapon" class support for weapon attachments. If a weapon attachment has the config property "baseWeapon" defined, it will take that item and show that in the arsenal. - Added stronger filtering on item scopes (scope > 0 at least for every item) - Added "descending" (default, as it is now) and "ascending" sort order as a drop down menu, - Unique backpacks in containers can now be removed with either the "-" or "clear all items" button. - When sorting by a number, 2 decimal points have been added, so that when you sort by weight it returns the correct order. --- addons/arsenal/XEH_postInit.sqf | 7 +- addons/arsenal/XEH_preInit.sqf | 4 - addons/arsenal/XEH_preStart.sqf | 4 + addons/arsenal/defines.hpp | 37 ++- .../arsenal/functions/fnc_addListBoxItem.sqf | 8 +- .../functions/fnc_addRightPanelButton.sqf | 4 +- .../arsenal/functions/fnc_addVirtualItems.sqf | 23 +- .../functions/fnc_attributeAddCompatible.sqf | 4 +- .../functions/fnc_attributeAddItems.sqf | 54 ++-- .../functions/fnc_attributeCategory.sqf | 2 +- .../arsenal/functions/fnc_attributeClear.sqf | 14 +- addons/arsenal/functions/fnc_baseWeapon.sqf | 72 ++--- addons/arsenal/functions/fnc_buttonCargo.sqf | 41 ++- .../arsenal/functions/fnc_buttonClearAll.sqf | 25 +- addons/arsenal/functions/fnc_buttonHide.sqf | 2 + .../functions/fnc_buttonLoadoutsRename.sqf | 2 +- .../functions/fnc_buttonLoadoutsSave.sqf | 2 + addons/arsenal/functions/fnc_compileStats.sqf | 4 +- .../arsenal/functions/fnc_fillLeftPanel.sqf | 2 +- .../functions/fnc_fillLoadoutsList.sqf | 6 +- .../arsenal/functions/fnc_fillRightPanel.sqf | 295 +++++++++--------- addons/arsenal/functions/fnc_fillSort.sqf | 33 +- .../arsenal/functions/fnc_onArsenalClose.sqf | 1 + .../arsenal/functions/fnc_onArsenalOpen.sqf | 19 +- .../functions/fnc_onSelChangedLeft.sqf | 33 +- .../functions/fnc_onSelChangedRight.sqf | 41 ++- .../fnc_onSelChangedRightListnBox.sqf | 11 +- addons/arsenal/functions/fnc_openBox.sqf | 4 +- .../fnc_replaceUniqueItemsLoadout.sqf | 24 +- addons/arsenal/functions/fnc_scanConfig.sqf | 32 +- addons/arsenal/functions/fnc_sortPanel.sqf | 63 ++-- .../functions/fnc_updateCurrentItemsList.sqf | 8 +- .../functions/fnc_updateRightPanel.sqf | 5 +- .../functions/fnc_updateUniqueItemsList.sqf | 23 +- .../arsenal/functions/fnc_verifyLoadout.sqf | 9 +- addons/arsenal/stringtable.xml | 6 + addons/arsenal/ui/RscAttributes.hpp | 11 +- addons/common/XEH_PREP.hpp | 1 + addons/common/functions/fnc_getAddon.sqf | 29 +- addons/common/functions/fnc_getConfigName.sqf | 28 +- .../common/functions/fnc_uniqueUnitItems.sqf | 47 +++ addons/laserpointer/CfgWeapons.hpp | 3 + docs/wiki/framework/arsenal-framework.md | 8 +- 43 files changed, 649 insertions(+), 402 deletions(-) create mode 100644 addons/common/functions/fnc_uniqueUnitItems.sqf diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index ccc1c582d75..93027b84719 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -9,9 +9,11 @@ GVAR(lastSearchTextRight) = ""; GVAR(lastSearchTextLoadouts) = ""; GVAR(lastSortLeft) = ""; GVAR(lastSortRight) = ""; +GVAR(lastSortDirectionLeft) = DESCENDING; +GVAR(lastSortDirectionRight) = DESCENDING; -[QGVAR(initBox), {LINKFUNC(initBox)}] call CBA_fnc_addEventHandler; -[QGVAR(removeBox), {LINKFUNC(removeBox)}] call CBA_fnc_addEventHandler; +[QGVAR(initBox), LINKFUNC(initBox)] call CBA_fnc_addEventHandler; +[QGVAR(removeBox), LINKFUNC(removeBox)] call CBA_fnc_addEventHandler; [QGVAR(broadcastFace), { params ["_unit", "_face"]; @@ -76,6 +78,7 @@ GVAR(lastSortRight) = ""; }; }; + // Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; // Select previously selected loadout diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 35710cbb132..1982f15780f 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -62,10 +62,6 @@ PREP_RECOMPILE_END; call FUNC(compileStats); call FUNC(compileSorts); -// Caches for names, pictures, mod icons -GVAR(addListBoxItemCache) = createHashMap; -GVAR(rightPanelCache) = createHashMap; - [QUOTE(ADDON), {!isNil QGVAR(camera)}] call CBA_fnc_registerFeatureCamera; // Compatibility with CBA scripted optics and disposable framework diff --git a/addons/arsenal/XEH_preStart.sqf b/addons/arsenal/XEH_preStart.sqf index 4284d8314ce..84411203073 100644 --- a/addons/arsenal/XEH_preStart.sqf +++ b/addons/arsenal/XEH_preStart.sqf @@ -5,4 +5,8 @@ // Cache for FUNC(baseWeapon) uiNamespace setVariable [QGVAR(baseWeaponNameCache), createHashMap]; +// Caches for names, pictures, mod icons +uiNamespace setVariable [QGVAR(addListBoxItemCache), createHashMap]; +uiNamespace setVariable [QGVAR(rightPanelCache), createHashMap]; + call FUNC(scanConfig); diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 5f7f34b6933..d9275aad45e 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -15,6 +15,10 @@ #define IDC_OK 1 // emulate "OK" button #define IDC_CANCEL 2 // emulate "Cancel" button +// Sorting +#define ASCENDING 0 +#define DESCENDING 1 + // IDCs #define IDD_ace_arsenal 1127001 #define IDC_mouseArea 0 @@ -46,7 +50,9 @@ #define IDC_rightTabContent 14 #define IDC_rightTabContentListnBox 15 #define IDC_sortLeftTab 16 +#define IDC_sortLeftTabDirection 161 #define IDC_sortRightTab 17 +#define IDC_sortRightTabDirection 171 #define IDC_leftSearchbar 18 #define IDC_leftSearchbarButton 41 #define IDC_rightSearchbar 19 @@ -173,6 +179,32 @@ #define IDC_ATTRIBUTE_IMPORT_BUTTON 8109 #define IDC_ATTRIBUTE_ADD_COMPATIBLE 8110 +// Indexes of categories +#define IDX_CAT_ALL 0 +#define IDX_CAT_PRIMARY_WEAPON 1 +#define IDX_CAT_SECONDARY_WEAPON 2 +#define IDX_CAT_HANDGUN_WEAPON 3 +#define IDX_CAT_OPTICS_ATTACHMENTS 4 +#define IDX_CAT_FLASHLIGHT_ATTACHMENTS 5 +#define IDX_CAT_MUZZLE_ATTACHMENTS 6 +#define IDX_CAT_BIPOD_ATTACHMENTS 7 +#define IDX_CAT_ITEMS_ALL 8 +#define IDX_CAT_HEADGEAR 9 +#define IDX_CAT_UNIFORM 10 +#define IDX_CAT_VEST 11 +#define IDX_CAT_BACKPACK 12 +#define IDX_CAT_GOGGLES 13 +#define IDX_CAT_NVG 14 +#define IDX_CAT_BINO 15 +#define IDX_CAT_MAP 16 +#define IDX_CAT_COMPASS 17 +#define IDX_CAT_RADIO 18 +#define IDX_CAT_WATCH 19 +#define IDX_CAT_COMMS 20 +#define IDX_CAT_GRENADES 21 +#define IDX_CAT_EXPLOSIVES 22 +#define IDX_CAT_MISC_ITEMS 23 + // Weapons 0 [primary, handgun, secondary] // Weapon attachements 1 [optics, flashlight, muzzle, bipod] // Magazines 2 @@ -226,7 +258,6 @@ #define IDX_VIRT_BIPOD_ATTACHMENTS 3 #define IDX_VIRT_ITEMS_ALL 2 - #define IDX_VIRT_HEADGEAR 3 #define IDX_VIRT_UNIFORM 4 #define IDX_VIRT_VEST 5 @@ -250,6 +281,7 @@ #define IDX_VIRT_UNIQUE_ATTACHMENTS 22 #define IDX_VIRT_UNIQUE_BACKPACKS 23 #define IDX_VIRT_UNIQUE_GOGGLES 24 +#define IDX_VIRT_UNIQUE_UNKNOWN_ITEMS 25 // Indexes of current items array #define IDX_CURR_PRIMARY_WEAPON 0 @@ -314,6 +346,7 @@ IDC_blockRighttBackground,\ IDC_rightTabContent,\ IDC_sortRightTab,\ + IDC_sortRightTabDirection,\ RIGHT_PANEL_ACC_IDCS,\ IDC_rightSearchbar,\ IDC_rightSearchbarButton,\ @@ -364,6 +397,7 @@ _buttonCurrentMag2Ctrl ctrlCommit FADE_DELAY;\ IDC_loadIndicator,\ IDC_rightTabContentListnBox,\ IDC_sortRightTab,\ + IDC_sortRightTabDirection,\ IDC_tabRight,\ RIGHT_PANEL_ACC_IDCS,\ RIGHT_PANEL_ITEMS_IDCS,\ @@ -446,6 +480,7 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\ IDC_rightTabContent,\ IDC_rightTabContentListnBox,\ IDC_sortRightTab,\ + IDC_sortRightTabDirection,\ RIGHT_PANEL_ACC_BACKGROUND_IDCS,\ RIGHT_PANEL_ACC_IDCS,\ RIGHT_PANEL_ITEMS_BACKGROUND_IDCS,\ diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index d0274c21ae5..80e7de0dfcc 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -4,7 +4,7 @@ * Add a listbox row. * * Arguments: - * 0: Config category, must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice" + * 0: Config category, must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice" or "CfgUnitInsignia" * 1: Classname * 2: Panel control * 3: Name of the picture entry in that Cfg class (default: "picture") @@ -21,16 +21,14 @@ params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]]; // Sanitise key, as it's public; If not in cache, find info and cache it for later use -private _cachedItemInfo = GVAR(addListBoxItemCache) getOrDefaultCall [toLower (_configCategory + _className), { +((uiNamespace getVariable QGVAR(addListBoxItemCache)) getOrDefaultCall [_configCategory + _className, { // Get classname (config case), display name, picture and DLC private _configPath = configFile >> _configCategory >> _className; private _dlcName = _configPath call EFUNC(common,getAddon); // If _pictureEntryName is empty, then this item has no picture (e.g. faces) [configName _configPath, getText (_configPath >> "displayName"), if (_pictureEntryName == "") then {""} else {getText (_configPath >> _pictureEntryName)}, if (_dlcName != "") then {(modParams [_dlcName, ["logo"]]) param [0, ""]} else {""}] -}, true]; - -_cachedItemInfo params ["_className", "_displayName", "_itemPicture", "_modPicture"]; +}, true]) params ["_className", "_displayName", "_itemPicture", "_modPicture"]; private _lbAdd = _ctrlPanel lbAdd _displayName; _ctrlPanel lbSetData [_lbAdd, _className]; diff --git a/addons/arsenal/functions/fnc_addRightPanelButton.sqf b/addons/arsenal/functions/fnc_addRightPanelButton.sqf index 60b5c5644b3..2cabe7d3e03 100644 --- a/addons/arsenal/functions/fnc_addRightPanelButton.sqf +++ b/addons/arsenal/functions/fnc_addRightPanelButton.sqf @@ -46,6 +46,7 @@ if (_position < 0 || {_position > 9}) exitWith { // If spot found, add items and return position private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; private _configItemInfo = ""; _items = _items select { @@ -53,7 +54,8 @@ _items = _items select { _x isKindOf ["CBA_MiscItem", _cfgWeapons] && {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} || {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} + {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} || + {getNumber (_cfgMagazines >> _x >> "ACE_isUnique") == 1} }; GVAR(customRightPanelButtons) set [_position, [_items apply {_x call EFUNC(common,getConfigName)}, _picture, _tooltip]]; diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index 22b5df63b90..aae2f5c07b4 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -30,7 +30,7 @@ if (_items isEqualType true) then { if (_items) then { private _weapons = _cargo select IDX_VIRT_WEAPONS; private _weaponAttachments = _cargo select IDX_VIRT_ATTACHMENTS; - private _configItems = uiNamespace getVariable QGVAR(configItems); + private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; // Add onto existing items, in case some items that were already added aren't available by default in the arsenal { @@ -71,6 +71,7 @@ if (_items isEqualType true) then { private _grenadeList = uiNamespace getVariable [QGVAR(grenadeCache), []]; private _putList = uiNamespace getVariable [QGVAR(putCache), []]; + private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), createHashMap]; // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 @@ -84,7 +85,7 @@ if (_items isEqualType true) then { _config = _cfgWeapons >> _x; // Check if valid class - if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { continue; }; @@ -97,16 +98,16 @@ if (_items isEqualType true) then { ): { switch (getNumber (_configItemInfo >> "type")) do { case TYPE_OPTICS: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS) pushBackUnique _x; + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); }; case TYPE_FLASHLIGHT: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) pushBackUnique _x; + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); }; case TYPE_MUZZLE: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS) pushBackUnique _x; + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); }; case TYPE_BIPOD: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS) pushBackUnique _x; + ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); }; }; }; @@ -199,12 +200,16 @@ if (_items isEqualType true) then { _config = _cfgMagazines >> _x; // Check if valid class - if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { continue; }; // Check what type the magazine actually is switch (true) do { + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + case (_x in _magazineMiscItems): { + (_cargo select IDX_VIRT_MISC_ITEMS) pushBackUnique _x; + }; // Grenades case (_x in _grenadeList): { (_cargo select IDX_VIRT_GRENADES) pushBackUnique _x; @@ -227,7 +232,7 @@ if (_items isEqualType true) then { _config = _cfgVehicles >> _x; // Check if valid class - if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { continue; }; @@ -240,7 +245,7 @@ if (_items isEqualType true) then { _config = _cfgGlasses >> _x; // Check if valid class - if !(((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal")} else {getNumber (_config >> "scope")}) == 2) && {getNumber (_config >> QGVAR(hide)) != 1}) then { + if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { continue; }; diff --git a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf index 1dbb8bc208c..318a4585c16 100644 --- a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf +++ b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf @@ -21,7 +21,7 @@ params ["_controlsGroup"]; private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); // Exit if selected category is not attachments or magazines -if !(_category in [4, 5, 6, 7, 8]) exitWith {}; +if !(_category in [IDX_CAT_OPTICS_ATTACHMENTS, IDX_CAT_FLASHLIGHT_ATTACHMENTS, IDX_CAT_MUZZLE_ATTACHMENTS, IDX_CAT_BIPOD_ATTACHMENTS, IDX_CAT_ITEMS_ALL]) exitWith {}; private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; @@ -33,7 +33,7 @@ private _attributeWeapons = _attributeItems arrayIntersect (flatten (_configItem // Add compatible attachments or magazines to attribute private _itemsToAdd = []; -if (_category == 8) then { +if (_category == IDX_CAT_ITEMS_ALL) then { // Get all compatible magazines for weapons { _itemsToAdd append (compatibleMagazines _x); diff --git a/addons/arsenal/functions/fnc_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf index 17183c4c554..555b1d3fa98 100644 --- a/addons/arsenal/functions/fnc_attributeAddItems.sqf +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -18,9 +18,10 @@ params ["_controlsGroup"]; -private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; +private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); private _filter = toLower ctrlText (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR); private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; +private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems", "_attributeMode"]; @@ -38,15 +39,15 @@ private _cfgVehicles = configFile >> "CfgVehicles"; private _cfgGlasses = configFile >> "CfgGlasses"; // Exit with current items (no specific category) -if (_category == -1) exitWith { +if (_category == IDX_CAT_ALL) exitWith { private _config = configNull; private _displayName = ""; - private _picture = ""; private _index = -1; { // Get appropriate config for each item (different since items can be from any category) _config = switch (true) do { + case (_x in _magazineMiscItems); case (_x in (_configItems select IDX_VIRT_ITEMS_ALL)); case (_x in (_configItems select IDX_VIRT_GRENADES)); case (_x in (_configItems select IDX_VIRT_EXPLOSIVES)): {_cfgMagazines >> _x}; @@ -59,70 +60,75 @@ if (_category == -1) exitWith { // Add item if not filtered if (_filter in (toLower _displayName) || {_filter in (toLower _x)}) then { - _picture = getText (_config >> "picture"); _index = _listbox lnbAddRow ["", _displayName, _modeSymbol]; _listbox lnbSetData [[_index, 1], _x]; - _listbox lnbSetPicture [[_index, 0], _picture]; - _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; + _listbox lnbSetPicture [[_index, 0], getText (_config >> "picture")]; + _listbox lnbSetTooltip [[_index, 0], _x]; }; } forEach _attributeItems; - _listbox lnbSort [1]; + // Sort alphabetically + _listbox lnbSort [1, false]; }; // Get list of category items private _categoryItems = switch (true) do { // Weapons - case (_category < 3): { - _configItems select IDX_VIRT_WEAPONS select _category; + case (_category < IDX_CAT_OPTICS_ATTACHMENTS): { + _configItems select IDX_VIRT_WEAPONS select (_category - 1) }; // Weapon attachments - case (_category < 7): { - _configItems select IDX_VIRT_ATTACHMENTS select (_category - 3); + case (_category < IDX_CAT_ITEMS_ALL): { + _configItems select IDX_VIRT_ATTACHMENTS select (_category - 4) }; // Other default { - _configItems select (_category - 5); + _configItems select (_category - 6) }; }; // Get config for current category -private _config = switch (true) do { - case (_category in [7, 20, 21]): {_cfgMagazines}; - case (_category == 11): {_cfgVehicles}; - case (_category == 12): {_cfgGlasses}; +private _cfgClass = switch (true) do { + case (_category in [IDX_CAT_ITEMS_ALL, IDX_CAT_GRENADES, IDX_CAT_EXPLOSIVES]): {_cfgMagazines}; + case (_category == IDX_CAT_BACKPACK): {_cfgVehicles}; + case (_category == IDX_CAT_GOGGLES): {_cfgGlasses}; default {_cfgWeapons}; }; private _displayName = ""; -private _picture = ""; private _symbol = SYMBOL_ITEM_NONE; private _alpha = 0; private _index = -1; +private _config = _cfgClass; // Populate listbox with category items { + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + if (_category == IDX_CAT_MISC_ITEMS) then { + _config = [_cfgClass, _cfgMagazines] select (_x in _magazineMiscItems); + }; + _displayName = getText (_config >> _x >> "displayName"); // Add item if not filtered if (_filter in (toLower _displayName) || {_filter in (toLower _x)}) then { - _picture = getText (_config >> _x >> "picture"); - _symbol = SYMBOL_ITEM_NONE; - _alpha = 0.5; - // Change symbol and alpha if item already selected if (_x in _attributeItems) then { _symbol = _modeSymbol; _alpha = 1; + } else { + _symbol = SYMBOL_ITEM_NONE; + _alpha = 0.5; }; _index = _listbox lnbAddRow ["", _displayName, _symbol]; _listbox lnbSetData [[_index, 1], _x]; - _listbox lnbSetPicture [[_index, 0], _picture]; - _listbox lbSetTooltip [_index * (count lnbGetColumnsPosition _listbox), _x]; + _listbox lnbSetPicture [[_index, 0], getText (_config >> _x >> "picture")]; + _listbox lnbSetTooltip [[_index, 0], _x]; _listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]]; _listbox lnbSetColor [[_index, 2], [1, 1, 1, _alpha]]; }; } forEach _categoryItems; -_listbox lnbSort [1]; +// Sort alphabetically +_listbox lnbSort [1, false]; diff --git a/addons/arsenal/functions/fnc_attributeCategory.sqf b/addons/arsenal/functions/fnc_attributeCategory.sqf index 990226ef3e5..435b1f1fd0b 100644 --- a/addons/arsenal/functions/fnc_attributeCategory.sqf +++ b/addons/arsenal/functions/fnc_attributeCategory.sqf @@ -24,7 +24,7 @@ uiNamespace setVariable [QGVAR(attributeCategory), _category]; // Show add compatible items button when category is attachments or magazines private _compatibleButton = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_ADD_COMPATIBLE; -private _enable = _category in [4, 5, 6, 7, 8]; +private _enable = _category in [IDX_CAT_OPTICS_ATTACHMENTS, IDX_CAT_FLASHLIGHT_ATTACHMENTS, IDX_CAT_MUZZLE_ATTACHMENTS, IDX_CAT_BIPOD_ATTACHMENTS, IDX_CAT_ITEMS_ALL]; _compatibleButton ctrlEnable _enable; _compatibleButton ctrlShow _enable; diff --git a/addons/arsenal/functions/fnc_attributeClear.sqf b/addons/arsenal/functions/fnc_attributeClear.sqf index 992c645a4ec..24156810f3e 100644 --- a/addons/arsenal/functions/fnc_attributeClear.sqf +++ b/addons/arsenal/functions/fnc_attributeClear.sqf @@ -18,28 +18,28 @@ params ["_controlsGroup"]; -private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) - 1; +private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; TRACE_1("Handling clear button",_category); // Remove all if no specific category -if (_category == -1) then { +if (_category == IDX_CAT_ALL) then { _attributeValue set [0, []]; } else { // Find category items and remove from list private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; private _categoryItems = switch (true) do { // Weapons - case (_category < 3): { - _configItems select IDX_VIRT_WEAPONS select _category; + case (_category < IDX_CAT_OPTICS_ATTACHMENTS): { + _configItems select IDX_VIRT_WEAPONS select (_category - 1) }; // Weapon attachments - case (_category < 7): { - _configItems select IDX_VIRT_ATTACHMENTS select (_category - 3); + case (_category < IDX_CAT_ITEMS_ALL): { + _configItems select IDX_VIRT_ATTACHMENTS select (_category - 4) }; // Other default { - _configItems select (_category - 5); + _configItems select (_category - 6) }; }; diff --git a/addons/arsenal/functions/fnc_baseWeapon.sqf b/addons/arsenal/functions/fnc_baseWeapon.sqf index 6d8fb4f72e3..4b5f3b52d68 100644 --- a/addons/arsenal/functions/fnc_baseWeapon.sqf +++ b/addons/arsenal/functions/fnc_baseWeapon.sqf @@ -18,47 +18,35 @@ params [["_weapon", "", [""]]]; -private _cacheKey = toLower _weapon; - // Check if item is cached -private _className = (uiNamespace getVariable QGVAR(baseWeaponNameCache)) get _cacheKey; - -if (!isNil "_className") exitWith { - _className -}; - -private _config = configfile >> "CfgWeapons" >> _weapon; - -// If class doesn't exist, exit -if (!isClass _config) exitWith { - (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _weapon]; - _weapon -}; - -// Get manual base weapon -private _configBase = configfile >> "CfgWeapons" >> getText (_config >> "baseWeapon"); - -if (isClass _configBase) exitWith { - _className = configName _configBase; - (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _className]; - _className -}; - -// Get first parent without any attachments -scopeName "main"; - -// Only take weapons available to the arsenal -// https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration -// https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 -while {isClass _config && {if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2} else {getNumber (_config >> "scope") > 0}} && {getNumber (_config >> QGVAR(hide)) != 1}} do { - if (count (_config >> "LinkedItems") == 0) exitWith { - _className = configName _config; - (uiNamespace getVariable QGVAR(baseWeaponNameCache)) set [_cacheKey, _className]; - _className breakOut "main" +(uiNamespace getVariable QGVAR(baseWeaponNameCache)) getOrDefaultCall [toLower _weapon, { + private _cfgWeapons = configfile >> "CfgWeapons"; + private _config = _cfgWeapons >> _weapon; + + // If class doesn't exist, exit + if (!isClass _config) then { + _weapon + } else { + // Get manual base weapon + private _configBase = _cfgWeapons >> getText (_config >> "baseWeapon"); + + if (isClass _configBase) then { + configName _configBase + } else { + private _className = _weapon; + + // Get first parent without any attachments; Only take weapons available to the arsenal + // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration + // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 + while {isClass _config && {getNumber (_config >> "scope") > 0 && {if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2} else {true}}} && {getNumber (_config >> QGVAR(hide)) != 1}} do { + if (count (_config >> "LinkedItems") == 0) exitWith { + _className = configName _config; + }; + + _config = inheritsFrom _config; + }; + + _className + }; }; - - _config = inheritsFrom _config; -}; - -_cache set [_cacheKey, _weapon]; -_weapon +}, true] diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index 170621d2f41..ca88125cff5 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -20,9 +20,10 @@ private _add = _addOrRemove > 0; private _ctrlList = _display displayCtrl IDC_rightTabContentListnBox; private _lnbCurSel = lnbCurSelRow _ctrlList; +private _isUnique = (_ctrlList lnbValue [_lnbCurSel, 2]) == 1; // If item is unique, don't allow adding more -if (_add && {(_ctrlList lnbValue [_lnbCurSel, 2]) == 1}) exitWith {}; +if (_add && {_isUnique}) exitWith {}; private _containerItems = []; private _item = _ctrlList lnbData [_lnbCurSel, 0]; @@ -36,12 +37,18 @@ private _container = switch (GVAR(currentLeftPanel)) do { GVAR(center) addItemToUniform _item; }; } else { - for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { - GVAR(center) removeItemFromUniform _item; + // Backpacks need special command to be removed + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) select IDX_VIRT_BACKPACK)}) then { + [uniformContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; + } else { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) removeItemFromUniform _item; + }; }; }; - _containerItems = uniformItems GVAR(center); + /// Get all items from container (excluding container itself) + _containerItems = [GVAR(center), 0, 3, 0, 0, false] call EFUNC(common,uniqueUnitItems); // Update currentItems GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_UNIFORM) param [1, []]]; @@ -58,12 +65,18 @@ private _container = switch (GVAR(currentLeftPanel)) do { GVAR(center) addItemToVest _item; }; } else { - for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { - GVAR(center) removeItemFromVest _item; + // Backpacks need special command to be removed + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) select IDX_VIRT_BACKPACK)}) then { + [vestContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; + } else { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) removeItemFromVest _item; + }; }; }; - _containerItems = vestItems GVAR(center); + // Get all items from container (excluding container itself) + _containerItems = [GVAR(center), 0, 0, 3, 0, false] call EFUNC(common,uniqueUnitItems); // Update currentItems GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_VEST) param [1, []]]; @@ -80,12 +93,18 @@ private _container = switch (GVAR(currentLeftPanel)) do { GVAR(center) addItemToBackpack _item; }; } else { - for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { - GVAR(center) removeItemFromBackpack _item; + // Backpacks need special command to be removed + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) select IDX_VIRT_BACKPACK)}) then { + [backpackContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; + } else { + for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { + GVAR(center) removeItemFromBackpack _item; + }; }; }; - _containerItems = backpackItems GVAR(center); + // Get all items from container (excluding container itself) + _containerItems = [GVAR(center), 0, 0, 0, 3, false] call EFUNC(common,uniqueUnitItems); // Update currentItems GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_BACKPACK) param [1, []]]; @@ -98,7 +117,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; // Find out how many items of that type there are and update the number displayed -_ctrlList lnbSetText [[_lnbCurSel, 2], str ({_x == _item} count _containerItems)]; +_ctrlList lnbSetText [[_lnbCurSel, 2], str (_containerItems getOrDefault [_item, 0])]; [QGVAR(cargoChanged), [_display, _item, _addOrRemove, GVAR(shiftState)]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonClearAll.sqf b/addons/arsenal/functions/fnc_buttonClearAll.sqf index 555a7143791..bec334e3403 100644 --- a/addons/arsenal/functions/fnc_buttonClearAll.sqf +++ b/addons/arsenal/functions/fnc_buttonClearAll.sqf @@ -19,26 +19,35 @@ params ["_display"]; private _container = switch (GVAR(currentLeftPanel)) do { // Uniform case IDC_buttonUniform: { - { - GVAR(center) removeItemFromUniform _x; - } forEach (vestItems GVAR(center)); + private _container = uniformContainer GVAR(center); + + // Remove everything (backpacks need special command for this) + clearWeaponCargoGlobal _container; + clearMagazineCargoGlobal _container; + clearItemCargoGlobal _container; + clearBackpackCargoGlobal _container; GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, []]; - uniformContainer GVAR(center) + _container }; // Vest case IDC_buttonVest: { - { - GVAR(center) removeItemFromVest _x; - } forEach (vestItems GVAR(center)); + private _container = vestContainer GVAR(center); + + // Remove everything (backpacks need special command for this) + clearWeaponCargoGlobal _container; + clearMagazineCargoGlobal _container; + clearItemCargoGlobal _container; + clearBackpackCargoGlobal _container; GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, []]; - vestContainer GVAR(center) + _container }; // Backpack case IDC_buttonBackpack: { + // Remove everything clearAllItemsFromBackpack GVAR(center); GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, []]; diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf index 1f149c5f3a6..8432982f7bc 100644 --- a/addons/arsenal/functions/fnc_buttonHide.sqf +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -36,6 +36,8 @@ private _ctrl = controlNull; IDC_rightTabContentListnBox, IDC_sortLeftTab, IDC_sortRightTab, + IDC_sortLeftTabDirection, + IDC_sortRightTabDirection, IDC_leftSearchbarButton, IDC_rightSearchbarButton, IDC_leftSearchbar, diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf index 5c321a45e97..9e7dc96c0ed 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf @@ -54,7 +54,7 @@ _contentPanelCtrl setVariable [_loadoutName + _currentLoadoutsTab, nil]; // Update the current row's loadout name _contentPanelCtrl lnbSetText [[_curSelRow, 1], _editBoxContent]; -// Sort alphabetically +// Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; // Select the newly renamed loadout diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf index 4fce9bb867f..554065c4256 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsSave.sqf @@ -96,6 +96,7 @@ private _savedLoadout = switch (GVAR(currentLoadoutsTab)) do { _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout] call FUNC(verifyLoadout)]; + // Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; // Select newly saved loadout @@ -137,6 +138,7 @@ private _savedLoadout = switch (GVAR(currentLoadoutsTab)) do { _contentPanelCtrl setVariable [_editBoxContent + str GVAR(currentLoadoutsTab), [_extendedLoadout] call FUNC(verifyLoadout)]; + // Sort loadouts alphabetically _contentPanelCtrl lnbSort [1, false]; // Select newly saved loadout diff --git a/addons/arsenal/functions/fnc_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf index 34442f946e1..276ed6c0c9f 100644 --- a/addons/arsenal/functions/fnc_compileStats.sqf +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -116,11 +116,11 @@ private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (confi TRACE_3("stats array", _finalArray, _leftTabsList, _rightTabsList); - if (count _leftTabsList > 0) then { + if (_leftTabsList isNotEqualTo []) then { [_statsListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs; }; - if (count _rightTabsList > 0) then { + if (_rightTabsList isNotEqualTo []) then { [_statsListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; }; } forEach _configEntries; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index 5aebc52eb29..69b42c04fd3 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -247,7 +247,7 @@ GVAR(currentLeftPanel) = _ctrlIDC; [QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent; // Sort -[_display, _control, _display displayCtrl IDC_sortLeftTab] call FUNC(fillSort); +[_display, _control, _display displayCtrl IDC_sortLeftTab, _display displayCtrl IDC_sortLeftTabDirection] call FUNC(fillSort); // Try to select previously selected item again, otherwise select first item ("Empty") if (_selectedItem != "") then { diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf index 92cca834c4c..19fbdaf757b 100644 --- a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -30,12 +30,12 @@ _contentPanelCtrl lnbSetCurSelRow -1; lnbClear _contentPanelCtrl; private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); +private _cfgWeapons = configFile >> "CfgWeapons"; +private _newRow = -1; if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { private _loadoutNameAndTab = ""; private _loadoutCachedInfo = ""; - private _newRow = -1; - private _cfgWeapons = configFile >> "CfgWeapons"; private _sharingEnabled = GVAR(allowSharedLoadouts) && {isMultiplayer}; // Add all loadouts to loadout list @@ -93,8 +93,6 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { } forEach ([profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); } else { private _allPlayerNames = allPlayers apply {name _x}; - private _newRow = -1; - private _cfgWeapons = configFile >> "CfgWeapons"; { _x params ["_playerName", "_loadoutName", "_loadoutData"]; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index d6a74421b13..1740e08826c 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -39,8 +39,13 @@ if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { _searchbarCtrl ctrlCommit 0; }; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; +private _rightPanelCache = uiNamespace getVariable [QGVAR(rightPanelCache), createHashMap]; + private _fnc_fill_right_Container = { - params ["_configCategory", "_className", "_isMagazine", ["_isUnique", false, [false]]]; + params ["_configCategory", "_className", "_hasItemInfo", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; // If item is not in the arsenal, it must be unique if (!_isUnique && {!(_className in GVAR(virtualItemsFlat))}) then { @@ -48,47 +53,54 @@ private _fnc_fill_right_Container = { }; // If not in cache, find info and cache it for later use - private _cachedItemInfo = GVAR(rightPanelCache) getOrDefaultCall [_configCategory + _className, { + (_rightPanelCache getOrDefaultCall [_configCategory + _className, { // Get display name, picture and mass private _configPath = configFile >> _configCategory >> _className; - [getText (_configPath >> "displayName"), getText (_configPath >> "picture"), if (_isMagazine) then {getNumber (_configPath >> "mass")} else {getNumber (_configPath >> "itemInfo" >> "mass")}] - }, true]; + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + if (_className in _magazineMiscItems) then { + _configPath = _cfgMagazines >> _className; + _hasItemInfo = false; + }; - _cachedItemInfo params ["_displayName", "_picture", "_mass"]; + // If an item with unknown origin is in the arsenal list, try to find it + if (_unknownOrigin && {isNull _configPath}) then { + _configPath = _className call CBA_fnc_getItemConfig; - private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; + // Check if item is object (this should never happen) + if (isNull _configPath) then { + _configPath = _className call CBA_fnc_getObjectConfig; + }; - _ctrlPanel lnbSetData [[_lbAdd, 0], _className]; - _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; - _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; - _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select _isUnique]; - _ctrlPanel lnbSetTooltip [[_lbAdd, 0], format ["%1\n%2", _displayName, _className]]; - _ctrlPanel setVariable [_className, _mass]; -}; + // Check if item is has item info + _itemInfo = isClass (_cfgWeapons >> configName _configPath); + }; -// Get all weapons on unit -private _weapons = [primaryWeapon GVAR(center), handgunWeapon GVAR(center), secondaryWeapon GVAR(center), binocular GVAR(center)]; -private _compatibleMagazines = []; -private _muzzles = []; + // Get mass + private _mass = if (!_hasItemInfo) then { + getNumber (_configPath >> "mass") + } else { + private _mass = getNumber (_configPath >> "itemInfo" >> "mass"); -// Get all compatibles magazines with unit's weapons -{ + if (_mass == 0) then { + _mass = getNumber (_configPath >> "WeaponSlotsInfo" >> "mass"); + }; - _muzzles = _x call CBA_fnc_getMuzzles; + _mass + }; - // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) - // Assumption: One weapon can have two muzzles maximum - _compatibleMagazines pushBack [compatibleMagazines [_x, _muzzles param [0, ""]], compatibleMagazines [_x, _muzzles param [1, ""]]]; -} forEach _weapons; + _rightPanelCache set [_className, _mass]; // Needed because this provides more accurate weight for FUNC(updateRightPanel) -// This is used for the "compatible magazines" tab when a container is open -private _allCompatibleMags = []; + [getText (_configPath >> "displayName"), getText (_configPath >> "picture"), _mass] + }, true]) params ["_displayName", "_picture", "_mass"]; -{ - _allCompatibleMags append (_x select 0); - _allCompatibleMags append (_x select 1); -} forEach _compatibleMagazines; + private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; + _ctrlPanel lnbSetData [[_lbAdd, 0], _className]; + _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; + _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; + _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select _isUnique]; + _ctrlPanel lnbSetTooltip [[_lbAdd, 0], format ["%1\n%2", _displayName, _className]]; +}; private _ctrlPanel = _display displayCtrl IDC_rightTabContent; private _listnBox = _display displayCtrl IDC_rightTabContentListnBox; @@ -102,45 +114,70 @@ _listnBox lbSetCurSel -1; // Retrieve compatible items private _compatibleItems = []; -private _itemsToCheck = []; -private _compatibleMagsPrimaryMuzzle = []; -private _compatibleMagsSecondaryMuzzle = []; +private _itemToCheck = ""; +private _allCompatibleMags = []; +private _compatibleMagsMuzzle = []; switch (GVAR(currentLeftPanel)) do { // If weapons or binoculars are chosen, get their compatible magazines & items - // Primary weapon - case IDC_buttonPrimaryWeapon: { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 0 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 0 select 1; - _compatibleItems = compatibleItems (_weapons select 0); - _itemsToCheck = GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS; - }; - // Handgun weapon - case IDC_buttonHandgun: { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 1 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 1 select 1; - _compatibleItems = compatibleItems (_weapons select 1); - _itemsToCheck = GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS; - }; - // Secondary weapon - case IDC_buttonSecondaryWeapon: { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 2 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 2 select 1; - _compatibleItems = compatibleItems (_weapons select 2); - _itemsToCheck = GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS; - }; - // Binoculars + // Weapons and binoculars + case IDC_buttonPrimaryWeapon; + case IDC_buttonHandgun; + case IDC_buttonSecondaryWeapon; case IDC_buttonBinoculars: { - _compatibleMagsPrimaryMuzzle = _compatibleMagazines select 3 select 0; - _compatibleMagsSecondaryMuzzle = _compatibleMagazines select 3 select 1; - _compatibleItems = compatibleItems (_weapons select 3); - _itemsToCheck = GVAR(currentItems) select IDX_CURR_BINO_ITEMS; + (switch (GVAR(currentLeftPanel)) do { + case IDC_buttonPrimaryWeapon: { + [IDX_CURR_PRIMARY_WEAPON, IDX_CURR_PRIMARY_WEAPON_ITEMS] + }; + case IDC_buttonHandgun: { + [IDX_CURR_HANDGUN_WEAPON, IDX_CURR_HANDGUN_WEAPON_ITEMS] + }; + case IDC_buttonSecondaryWeapon: { + [IDX_CURR_SECONDARY_WEAPON, IDX_CURR_SECONDARY_WEAPON_ITEMS] + }; + case IDC_buttonBinoculars: { + [IDX_CURR_BINO, IDX_CURR_BINO_ITEMS] + }; + }) params ["_currentWeaponIndex", "_currentWeaponItemsIndex"]; + + private _index = [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find _ctrlIDC; + private _weapon = GVAR(currentItems) select _currentWeaponIndex; + + // Check if weapon attachement or magazine + if (_index != -1) then { + _itemToCheck = (GVAR(currentItems) select _currentWeaponItemsIndex) select _index; + + // If weapon attachment, get base weapon; Get compatible items + if (_index <= 3) then { + _compatibleItems = compatibleItems _weapon; + _itemToCheck = _itemToCheck call FUNC(baseWeapon); + } else { + // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) + // Assumption: One weapon can have two muzzles maximum + _compatibleMagsMuzzle = compatibleMagazines [_weapon, (_weapon call CBA_fnc_getMuzzles) param [_index - 4, ""]]; + }; + }; }; // Uniform, vest or backpack case IDC_buttonUniform; case IDC_buttonVest; case IDC_buttonBackpack: { _ctrlPanel = _listnBox; + + // This is for the "compatible magazines" tab when a container is open + if (_ctrlIDC == IDC_buttonMag) then { + private _muzzles = []; + + // Get all compatibles magazines with unit's weapons + { + _muzzles = _x call CBA_fnc_getMuzzles; + + // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) + // Assumption: One weapon can have two muzzles maximum + _allCompatibleMags append (compatibleMagazines [_x, _muzzles param [0, ""]]); + _allCompatibleMags append (compatibleMagazines [_x, _muzzles param [1, ""]]); + } forEach [GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON, GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON, GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON, GVAR(currentItems) select IDX_CURR_BINO]; + }; }; }; @@ -161,124 +198,74 @@ if (_leftPanelState && {_ctrlIDC in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, // Fill right panel according to category choice switch (_ctrlIDC) do { - // Optics - case IDC_buttonOptic: { - if (_leftPanelState) then { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS)) arrayIntersect _compatibleItems); - } else { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS); - - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS); - }; - }; - // Flashlights - case IDC_buttonItemAcc: { - if (_leftPanelState) then { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)) arrayIntersect _compatibleItems); - } else { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS); - - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS); - }; - }; - // Muzzle attachments - case IDC_buttonMuzzle: { - if (_leftPanelState) then { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS)) arrayIntersect _compatibleItems); - } else { - { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS); - - { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS); - }; - }; - // Bipods + // Optics, flashlights, muzzle attachments, bipods + case IDC_buttonOptic; + case IDC_buttonItemAcc; + case IDC_buttonMuzzle; case IDC_buttonBipod: { + private _index = [IDX_VIRT_OPTICS_ATTACHMENTS, IDX_VIRT_FLASHLIGHT_ATTACHMENTS, IDX_VIRT_MUZZLE_ATTACHMENTS, IDX_VIRT_BIPOD_ATTACHMENTS] select ([RIGHT_PANEL_ACC_IDCS] find _ctrlIDC); + if (_leftPanelState) then { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS)) arrayIntersect _compatibleItems); + } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _index)) arrayIntersect _compatibleItems); } else { { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS); + ["CfgWeapons", _x, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _index); { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS); + ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select _index); }; }; - // Current primary muzzle compatible magazines - case IDC_buttonCurrentMag: { - if (_leftPanelState) then { - { - ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsPrimaryMuzzle); - }; - }; - // Current secondary muzzle compatible magazines + // Current primary & secondary muzzle compatible magazines + case IDC_buttonCurrentMag; case IDC_buttonCurrentMag2: { if (_leftPanelState) then { { ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsSecondaryMuzzle); + } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsMuzzle); }; }; // All compatible magazines case IDC_buttonMag: { { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); }; // All magazines case IDC_buttonMagALL: { { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false] call _fnc_fill_right_Container; } forEach (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL); }; // Grenades case IDC_buttonThrow: { { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false] call _fnc_fill_right_Container; } forEach (GVAR(virtualItems) select IDX_VIRT_GRENADES); { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GRENADES); }; // Explosives case IDC_buttonPut: { { - ["CfgMagazines", _x, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false] call _fnc_fill_right_Container; } forEach (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES); { - ["CfgMagazines", _x, true, true] call _fnc_fill_right_Container; + ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_EXPLOSIVES); }; // Misc. items @@ -296,11 +283,11 @@ switch (_ctrlIDC) do { // "Regular" misc. items { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS) select {!(_x in _items)}); // Unique items { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) select {!(_x in _items)}); // Unique backpacks { @@ -310,6 +297,10 @@ switch (_ctrlIDC) do { { ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) select {!(_x in _items)}); + // Unknown items + { + ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) select {!(_x in _items)}); }; // Custom buttons default { @@ -318,11 +309,11 @@ switch (_ctrlIDC) do { if (_items isNotEqualTo []) then { // "Regular" misc. items { - ["CfgWeapons", _x, false] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS) select {_x in _items}); // Unique items { - ["CfgWeapons", _x, false, true] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) select {_x in _items}); // Unique backpacks { @@ -332,13 +323,20 @@ switch (_ctrlIDC) do { { ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) select {_x in _items}); + // Unknown items + { + ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; + } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) select {_x in _items}); }; }; }; -// Reset right panel search bar -(_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +// When switching tabs, clear searchbox +if (GVAR(currentRightPanel) != _ctrlIDC) then { + (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +}; +// Trigger event GVAR(currentRightPanel) = _ctrlIDC; [QGVAR(rightPanelFilled), [_display, GVAR(currentLeftPanel), _ctrlIDC]] call CBA_fnc_localEvent; @@ -351,7 +349,8 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); - _containerItems = uniformItems GVAR(center); + // Get all items from container (excluding container itself) + _containerItems = [GVAR(center), 0, 3, 0, 0, false] call EFUNC(common,uniqueUnitItems); uniformContainer GVAR(center) }; @@ -360,7 +359,8 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); - _containerItems = vestItems GVAR(center); + // Get all items from container (excluding container itself) + _containerItems = [GVAR(center), 0, 0, 3, 0, false] call EFUNC(common,uniqueUnitItems); vestContainer GVAR(center) }; @@ -369,18 +369,16 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); - _containerItems = backpackItems GVAR(center); + // Get all items from container (excluding container itself) + _containerItems = [GVAR(center), 0, 0, 0, 3, false] call EFUNC(common,uniqueUnitItems); backpackContainer GVAR(center) }; }; // Find out how many items of a type there are and update the number displayed - private _class = ""; - for "_lbIndex" from 0 to (lnbSize _ctrlPanel select 0) - 1 do { - _class = _ctrlPanel lnbData [_lbIndex, 0]; - _ctrlPanel lnbSetText [[_lbIndex, 2], str ({_x == _class} count _containerItems)]; + _ctrlPanel lnbSetText [[_lbIndex, 2], str (_containerItems getOrDefault [_ctrlPanel lnbData [_lbIndex, 0], 0])]; }; // Refresh availibility of items based on space remaining in container @@ -388,17 +386,14 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack }; // Sorting -[_display, _control, _display displayCtrl IDC_sortRightTab] call FUNC(fillSort); - -// Remove empty entries (for comparison below) -_itemsToCheck = _itemsToCheck - [""]; +[_display, _control, _display displayCtrl IDC_sortRightTab, _display displayCtrl IDC_sortRightTabDirection] call FUNC(fillSort); // Try to select previously selected item again, otherwise select first item ("Empty") -if (_itemsToCheck isNotEqualTo []) then { +if (_itemToCheck != "") then { private _index = 0; for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { - if ((_ctrlPanel lbData _lbIndex) in _itemsToCheck) exitWith { + if ((_ctrlPanel lbData _lbIndex) == _itemToCheck) exitWith { _index = _lbIndex; }; }; diff --git a/addons/arsenal/functions/fnc_fillSort.sqf b/addons/arsenal/functions/fnc_fillSort.sqf index 213b124e3ec..7f2f47f9140 100644 --- a/addons/arsenal/functions/fnc_fillSort.sqf +++ b/addons/arsenal/functions/fnc_fillSort.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, Brett Mayson + * Author: Alganthe, Brett Mayson, johnb43 * Fills the sort menu. * * Arguments: @@ -15,13 +15,36 @@ * Public: No */ -params ["_display", "_control", "_sortCtrl"]; +params ["_display", "_control", "_sortCtrl", "_sortDirectionCtrl"]; lbClear _sortCtrl; +lbClear _sortDirectionCtrl; private _right = false; private _rightSort = ctrlIDC _sortCtrl == IDC_sortRightTab; +// Handle sorting direction +private _lastSortDirection = [GVAR(lastSortDirectionLeft), GVAR(lastSortDirectionRight)] select _rightSort; +private _sortIndex = 0; +private _index = -1; + +{ + _x params ["_sortName", "_displayName", "_direction"]; + + _index = _sortDirectionCtrl lbAdd _displayName; + _sortDirectionCtrl lbSetData [_index, _sortName]; + _sortDirectionCtrl lbSetValue [_index, _direction]; + + if (_direction == _lastSortDirection) then { + _sortIndex = _index; + }; +} forEach [[QGVAR(descending), LLSTRING(sortDescending), DESCENDING], [QGVAR(ascending), LLSTRING(sortAscending), ASCENDING]]; + +// Prevent FUNC(sortPanel) being called twice in succession +GVAR(ignoreFirstSortPanelCall) = true; +_sortDirectionCtrl lbSetCurSel _sortIndex; + +// Handle sorting private _sorts = if (_rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}) then { _right = true; @@ -90,7 +113,7 @@ private _sorts = if (_rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform }; private _lastSort = [GVAR(lastSortLeft), GVAR(lastSortRight)] select _rightSort; -private _sortIndex = 0; +_sortIndex = 0; { if (_x isEqualTo []) then { @@ -101,10 +124,10 @@ private _sortIndex = 0; // Check if sort if available for this panel if ([_right] call _condition) then { - private _index = _sortCtrl lbAdd _displayName; + _index = _sortCtrl lbAdd _displayName; _sortCtrl lbSetData [_index, _sortName]; - if (_displayName isEqualTo _lastSort) then { + if (_displayName == _lastSort) then { _sortIndex = _index; }; }; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index d19fc63df07..4b86591bfba 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -108,6 +108,7 @@ GVAR(shiftState) = nil; GVAR(leftTabFocus) = nil; GVAR(rightTabFocus) = nil; GVAR(rightTabLnBFocus) = nil; +GVAR(ignoreFirstSortPanelCall) = nil; GVAR(selectedWeaponType) = nil; GVAR(virtualItems) = nil; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index 51c40b5d2ec..ccc216feb6f 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -72,20 +72,18 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; if (_weapon != "") then { _weapon = _weapon call FUNC(baseWeapon); - if (_weapon != "") then { - // If bino, add it in a different place than regular weapons - if (_forEachIndex != IDX_LOADOUT_BINO) then { - (GVAR(virtualItems) select IDX_VIRT_WEAPONS select _forEachIndex) pushBackUnique _weapon; - } else { - (GVAR(virtualItems) select IDX_VIRT_BINO) pushBackUnique _weapon; - }; + // If bino, add it in a different place than regular weapons + if (_forEachIndex != IDX_LOADOUT_BINO) then { + ((GVAR(virtualItems) select IDX_VIRT_WEAPONS) select _forEachIndex) pushBackUnique _weapon; + } else { + (GVAR(virtualItems) select IDX_VIRT_BINO) pushBackUnique _weapon; }; }; // Add weapon attachments { if (_x != "") then { - ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _forEachIndex) pushBackUnique _x; + ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _forEachIndex) pushBackUnique (_x call FUNC(baseWeapon)); }; } forEach [_optics, _flashlight, _muzzle, _bipod]; @@ -110,7 +108,7 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; _x params [["_containerClass", ""]]; if (_containerClass != "") then { - (GVAR(virtualItems) select IDX_CURR_VEST) pushBackUnique _containerClass; + (GVAR(virtualItems) select IDX_VIRT_VEST) pushBackUnique _containerClass; }; }; // Backpack @@ -118,7 +116,7 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; _x params [["_containerClass", ""]]; if (_containerClass != "") then { - (GVAR(virtualItems) select IDX_CURR_BACKPACK) pushBackUnique _containerClass; + (GVAR(virtualItems) select IDX_VIRT_BACKPACK) pushBackUnique _containerClass; }; }; // Helmet @@ -285,6 +283,7 @@ GVAR(rightSearchbarFocus) = false; GVAR(leftTabFocus) = false; GVAR(rightTabFocus) = false; GVAR(rightTabLnBFocus) = false; +GVAR(ignoreFirstSortPanelCall) = false; { private _panel = _display displayCtrl _x; diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 7dff2878697..ef85be138f4 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -2,7 +2,7 @@ #include "..\defines.hpp" #include "\a3\ui_f\hpp\defineResincl.inc" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Handles selection changes on the left panel. * * Arguments: @@ -28,16 +28,16 @@ private _selectCorrectPanelContainer = [_display displayCtrl IDC_buttonMisc, _di // Remove all magazines from the previous weapon that aren't compatible with the new weapon private _fnc_clearPreviousWepMags = { - private _compatibleMagsBaseWeapon = compatibleMagazines _baseWeapon; + private _compatibleMagsCurrentWeapon = compatibleMagazines _currentWeapon; // If nothing was selected, remove all magazines from the previous weapon if (_item != "") then { - _compatibleMagsBaseWeapon = _compatibleMagsBaseWeapon - _compatibleMags; + _compatibleMagsCurrentWeapon = _compatibleMagsCurrentWeapon - _compatibleMags; }; { GVAR(center) removeMagazines _x; - } forEach _compatibleMagsBaseWeapon; + } forEach _compatibleMagsCurrentWeapon; // Update currentItems private _loadout = getUnitLoadout GVAR(center); @@ -51,7 +51,7 @@ private _fnc_clearPreviousWepMags = { switch (GVAR(currentLeftPanel)) do { // Primary weapon case IDC_buttonPrimaryWeapon: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) call FUNC(baseWeapon); + private _currentWeapon = GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON; // If nothing selected, remove primary weapon and its magazines if (_item == "") then { @@ -64,7 +64,7 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_HIDE } else { // Check if a new primary weapon was selected - if ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON) != _item && {_baseWeapon != _item}) then { + if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); @@ -119,7 +119,7 @@ switch (GVAR(currentLeftPanel)) do { }; // Handgun weapon case IDC_buttonHandgun: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) call FUNC(baseWeapon); + private _currentWeapon = GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON; // If nothing selected, remove handgun weapon and its magazines if (_item == "") then { @@ -132,7 +132,7 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_HIDE } else { // Check if a new handgun weapon was selected - if ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON) != _item && {_baseWeapon != _item}) then { + if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); @@ -188,7 +188,7 @@ switch (GVAR(currentLeftPanel)) do { }; // Secondary weapon case IDC_buttonSecondaryWeapon: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) call FUNC(baseWeapon); + private _currentWeapon = GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON; // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { @@ -201,7 +201,7 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_HIDE } else { // Check if a new secondary weapon was selected - if ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON) != _item && {_baseWeapon != _item}) then { + if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); @@ -245,7 +245,14 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_WEAPON - [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); + // If item is a disposable launcher, delay a bit to show new compatible items + if (_item in (uiNamespace getVariable [QGVAR(CBAdisposableLaunchers), []])) then { + [{ + _this call FUNC(fillRightPanel); + }, [_display, _selectCorrectPanelWeapon]] call CBA_fnc_execNextFrame; + } else { + [_display, _selectCorrectPanelWeapon] call FUNC(fillRightPanel); + }; }; // Make unit switch to new item @@ -434,7 +441,7 @@ switch (GVAR(currentLeftPanel)) do { }; // Binoculars case IDC_buttonBinoculars: { - private _baseWeapon = (GVAR(currentItems) select IDX_CURR_BINO) call FUNC(baseWeapon); + private _currentWeapon = GVAR(currentItems) select IDX_CURR_BINO; // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { @@ -447,7 +454,7 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_HIDE } else { // Check if a new binocular was selected - if ((GVAR(currentItems) select IDX_CURR_BINO) != _item && {_baseWeapon != _item}) then { + if (_item != _currentWeapon) then { // Get magazines that are compatible with the new binocular private _compatibleMags = compatibleMagazines _item; private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index 1f464a917e4..1a0bf1b8ed3 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -31,7 +31,12 @@ switch (_currentItemsIndex) do { if (_item == "") then { GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex); } else { - GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; + private _currentItem = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex; + + // Don't add item if it isn't a different item than what the unit already has + if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; + }; }; // Update currentItems @@ -42,20 +47,26 @@ switch (_currentItemsIndex) do { }; // Secondary weapon case IDX_CURR_SECONDARY_WEAPON_ITEMS: { + private _cbaDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; + + // If removal if (_item == "") then { - if (CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}) exitWith { + if (_cbaDisposable) exitWith { TRACE_1("ignoring unload of disposable",secondaryWeapon GVAR(center)); }; GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex); - - // Update currentItems - (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; } else { - GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; + private _currentItem = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; - // Update currentItems + // Don't add item if it isn't a different item than what the unit already has + if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; + }; + }; + + // Update currentItems + if (!_cbaDisposable) then { (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; }; @@ -67,7 +78,12 @@ switch (_currentItemsIndex) do { if (_item == "") then { GVAR(center) removeHandgunItem ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex); } else { - GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; + private _currentItem = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex; + + // Don't add item if it isn't a different item than what the unit already has + if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; + }; }; // Update currentItems @@ -81,7 +97,12 @@ switch (_currentItemsIndex) do { if (_item == "") then { GVAR(center) removeBinocularItem ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex); } else { - GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; + private _currentItem = (GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex; + + // Don't add item if it isn't a different item than what the unit already has + if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; + }; }; // Update currentItems diff --git a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf index 638f2af2a30..d2ee2a231f6 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRightListnBox.sqf @@ -43,7 +43,14 @@ private _container = switch (GVAR(currentLeftPanel)) do { [_control, _container, _hasItems] call FUNC(updateRightPanel); private _item = _control lnbData [_curSel, 0]; -private _cfgEntry = ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut]); +private _cfgEntry = ["CfgWeapons", "CfgMagazines"] select (GVAR(currentRightPanel) in [IDC_buttonMag, IDC_buttonMagALL, IDC_buttonThrow, IDC_buttonPut] || {_item in (uiNamespace getVariable [QGVAR(magazineMiscItems), []])}); + +_cfgEntry = configFile >> _cfgEntry >> _item; + +// If e.g. in misc. items, item could be e.g. a backpack +if (isNull _cfgEntry) then { + _cfgEntry = _item call CBA_fnc_getItemConfig; +}; // Display item info on the bottom right -[ctrlParent _control, _control, _curSel, configFile >> _cfgEntry >> _item] call FUNC(itemInfo); +[ctrlParent _control, _control, _curSel, _cfgEntry] call FUNC(itemInfo); diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf index 29416be45e2..b4c6760101f 100644 --- a/addons/arsenal/functions/fnc_openBox.sqf +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -50,8 +50,8 @@ GVAR(currentBox) = _object; if (_mode) then { // Add all the items from the game that the arsenal has detected - GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); - GVAR(virtualItemsFlat) = +(uiNamespace getVariable QGVAR(configItemsFlat)); + GVAR(virtualItems) = +(uiNamespace getVariable [QGVAR(configItems), []]); + GVAR(virtualItemsFlat) = +(uiNamespace getVariable [QGVAR(configItemsFlat), []]); } else { // Add only specified items to the arsenal GVAR(virtualItems) = +(_object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]); diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf index 0ce36717c8c..b6c0921d10d 100644 --- a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -26,6 +26,7 @@ if (count _loadout == 2) then { if (count _loadout != 10) exitWith {[]}; private _weapon = ""; +private _weaponsInfo = []; private _uniqueBaseCfgText = ""; private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; @@ -38,12 +39,19 @@ private _cfgVehicles = configFile >> "CfgVehicles"; case IDX_LOADOUT_SECONDARY_WEAPON; case IDX_LOADOUT_HANDGUN_WEAPON; case IDX_LOADOUT_BINO: { - _x params [["_weapon", ""]]; + _weaponsInfo = _x; - // Find baseweapon of weapon - if (_weapon != "") then { - _x set [0, _weapon call FUNC(baseWeapon)]; - }; + // Check weapon & weapon attachments + { + // Skip magazines + if (_forEachIndex in [4, 5]) then { + continue; + }; + + if (_x != "") then { + _weaponsInfo set [_forEachIndex, _x call FUNC(baseWeapon)]; + }; + } forEach _weaponsInfo; }; // Uniform, vest, backpack case IDX_LOADOUT_UNIFORM; @@ -61,7 +69,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; _x params ["_item", "_arg"]; if (_item != "") then { - _uniqueBaseCfgText = getText ([_cfgVehicles, _cfgWeapons] select (_arg isEqualType 0) >> _item >> QGVAR(uniqueBase)); + _uniqueBaseCfgText = (getText ([_cfgWeapons, _cfgVehicles] select ((_arg isEqualType false) && {_arg}) >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); if (_uniqueBaseCfgText != "") then { _x set [0, _uniqueBaseCfgText]; @@ -81,7 +89,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; _x params ["_item"]; if (_item != "") then { - _uniqueBaseCfgText = getText (_cfgMagazines >> _item >> QGVAR(uniqueBase)); + _uniqueBaseCfgText = (getText (_cfgMagazines >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); if (_uniqueBaseCfgText != "") then { _x set [0, _uniqueBaseCfgText]; @@ -98,7 +106,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; { if (_x != "") then { - _uniqueBaseCfgText = getText (_cfgWeapons >> _x >> QGVAR(uniqueBase)); + _uniqueBaseCfgText = (getText (_cfgWeapons >> _x >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); if (_uniqueBaseCfgText != "") then { _items set [_forEachIndex, _uniqueBaseCfgText]; diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index ae31436709e..8d0caaba7cf 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -18,7 +18,7 @@ private _configItems = EMPTY_VIRTUAL_ARSENAL; // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 private _filterFunction = toString { - isClass _x && {(if (isNumber (_x >> "scopeArsenal")) then {getNumber (_x >> "scopeArsenal")} else {getNumber (_x >> "scope")}) == 2} && {getNumber (_x >> QGVAR(hide)) != 1} + isClass _x && {if (isNumber (_x >> "scopeArsenal")) then {getNumber (_x >> "scopeArsenal") == 2 && {getNumber (_x >> "scope") > 0}} else {getNumber (_x >> "scope") == 2}} && {getNumber (_x >> QGVAR(hide)) != 1} }; private _cfgWeapons = configFile >> "CfgWeapons"; @@ -47,7 +47,7 @@ private _isMiscItem = false; {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]} ): { // Convert type to array index - ((_configItems select IDX_VIRT_ATTACHMENTS) select ([TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] find _itemInfoType)) pushBackUnique _className; + ((_configItems select IDX_VIRT_ATTACHMENTS) select ([TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] find _itemInfoType)) pushBackUnique (_className call FUNC(baseWeapon)); }; // Headgear case (_itemInfoType == TYPE_HEADGEAR): { @@ -80,7 +80,7 @@ private _isMiscItem = false; case (_simulationType == "ItemCompass"): { (_configItems select IDX_VIRT_COMPASS) pushBackUnique _className; }; - // Radio// + // Radio case (_simulationType == "ItemRadio"): { (_configItems select IDX_VIRT_RADIO) pushBackUnique _className; }; @@ -112,7 +112,7 @@ private _isMiscItem = false; }; }; }; - // Misc items + // Misc. items case ( _hasItemInfo && {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] && @@ -147,11 +147,18 @@ _putList = _putList apply {_x call EFUNC(common,getConfigName)}; _grenadeList = _grenadeList - [""]; _putList = _putList - [""]; +private _magazineMiscItems = []; + // Get all other grenades, explosives (and similar) and magazines { _className = configName _x; switch (true) do { + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + case (getNumber (_x >> "ACE_isUnique") == 1): { + (_configItems select IDX_VIRT_MISC_ITEMS) pushBackUnique _className; + _magazineMiscItems pushBackUnique _className; + }; // Grenades case (_className in _grenadeList): { (_configItems select IDX_VIRT_GRENADES) pushBackUnique _className; @@ -212,6 +219,21 @@ private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x & // Get all insignia private _insigniaCache = "true" configClasses (configFile >> "CfgUnitInsignia"); +// Get all disposable launchers +private _launchersConfig = configProperties [configFile >> "CBA_DisposableLaunchers"]; +private _launchers = []; + +// Get the loaded launchers (used launchers aren't necessary) +{ + _launchers pushBackUnique ((getArray _x) param [0, ""]); +} forEach _launchersConfig; + +// Convert list to config case +_launchers = _launchers apply {_x call EFUNC(common,getConfigName)}; + +// Remove invalid/non-existent entries +_launchers = _launchers - [""]; + // This contains config case entries only uiNamespace setVariable [QGVAR(configItems), _configItems]; uiNamespace setVariable [QGVAR(configItemsFlat), flatten _configItems]; @@ -220,3 +242,5 @@ uiNamespace setVariable [QGVAR(voiceCache), _voiceCache]; uiNamespace setVariable [QGVAR(insigniaCache), _insigniaCache]; uiNamespace setVariable [QGVAR(grenadeCache), _grenadeList]; uiNamespace setVariable [QGVAR(putCache), _putList]; +uiNamespace setVariable [QGVAR(CBAdisposableLaunchers), _launchers]; +uiNamespace setVariable [QGVAR(magazineMiscItems), _magazineMiscItems]; diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index ec40beb1c81..b37ae37f022 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -5,7 +5,7 @@ * Sort an arsenal panel. * * Arguments: - * 0: Sort control + * 0: Control * * Return Value: * None @@ -13,12 +13,20 @@ * Public: No */ -params ["_sortControl"]; +params ["_control"]; -private _display = ctrlParent _sortControl; +// When filling the sorting panel, FUNC(sortPanel) is called twice, so ignore first call +if (GVAR(ignoreFirstSortPanelCall)) exitWith { + GVAR(ignoreFirstSortPanelCall) = false; +}; -private _rightSort = ctrlIDC _sortControl == IDC_sortRightTab; +private _display = ctrlParent _control; +private _rightSort = (ctrlIDC _control) in [IDC_sortRightTab, IDC_sortRightTabDirection]; private _right = _rightSort && {GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]}; +private _sortCtrl = _display displayCtrl ([IDC_sortLeftTab, IDC_sortRightTab] select _rightSort); +private _sortDirectionCtrl = _display displayCtrl ([IDC_sortLeftTabDirection, IDC_sortRightTabDirection] select _rightSort); + +private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgFaces = configFile >> "CfgFaces"; private _cfgUnitInsignia = configFile >> "CfgUnitInsignia"; private _cfgUnitInsigniaMission = missionConfigFile >> "CfgUnitInsignia"; @@ -36,7 +44,7 @@ if (_rightSort) then { case IDC_buttonThrow; case IDC_buttonPut; case IDC_buttonMag; - case IDC_buttonMagALL: {configFile >> "CfgMagazines"}; + case IDC_buttonMagALL: {_cfgMagazines}; default {configFile >> "CfgWeapons"}; }, GVAR(sortListRightPanel) select ( @@ -89,6 +97,22 @@ if (_rightSort) then { ] } params ["_panel", "_cfgClass", "_sorts"]; +// Get sort & sort direction +private _sortName = _sortCtrl lbData (0 max lbCurSel _sortCtrl); +private _sortDirection = _sortDirectionCtrl lbValue (0 max lbCurSel _sortDirectionCtrl); +(_sorts select (0 max (_sorts findIf {(_x select 0) == _sortName}))) params ["", "_displayName", "_statement"]; + +// Update last sort & sort direction +missionNamespace setVariable [ + [QGVAR(lastSortLeft), QGVAR(lastSortRight)] select _rightSort, + _displayName +]; + +missionNamespace setVariable [ + [QGVAR(lastSortDirectionLeft), QGVAR(lastSortDirectionRight)] select _rightSort, + _sortDirection +]; + // Get currently selected item private _curSel = if (_right) then { lnbCurSelRow _panel @@ -102,18 +126,6 @@ private _selected = if (_right) then { _panel lbData _curSel }; -// Get sort's information -private _sortName = _sortControl lbData (0 max lbCurSel _sortControl); -private _sortConfig = _sorts select (0 max (_sorts findIf {(_x select 0) isEqualTo _sortName})); -private _statement = _sortConfig select 2; -_sortConfig params ["", "", "_statement"]; - -// Update last sort -missionNamespace setVariable [ - [QGVAR(lastSortLeft), QGVAR(lastSortRight)] select _rightSort, - _sortConfig select 1 -]; - private _originalNames = createHashMap; private _item = ""; private _quantity = ""; @@ -121,6 +133,8 @@ private _itemCfg = configNull; private _value = ""; private _name = ""; +private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; + private _faceCache = if (_cfgClass == _cfgFaces) then { uiNamespace getVariable [QGVAR(faceCache), createHashMap] } else { @@ -154,6 +168,11 @@ _for do { 0 }; + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + if (_item in _magazineMiscItems) then { + _cfgClass = _cfgMagazines; + }; + // Check item's config _itemCfg = if !(_cfgClass in [_cfgFaces, _cfgUnitInsignia]) then { _cfgClass >> _item @@ -173,7 +192,7 @@ _for do { }; }; - // Some items may not belong to the config class for the panel (misc. items panel can have unique items) + // Some items may not belong to the config class for the panel (e.g. misc. items panel can have unique items) if (isNull _itemCfg) then { _itemCfg = _item call CBA_fnc_getItemConfig; }; @@ -181,9 +200,9 @@ _for do { // Value can be any type _value = [_itemCfg, _item, _quantity] call _statement; - // If number, convert to string + // If number, convert to string (keep 2 decimal after comma; Needed for correct weight sorting) if (_value isEqualType 0) then { - _value = [_value, 8] call CBA_fnc_formatNumber; + _value = [_value, 8, 2] call CBA_fnc_formatNumber; }; // If empty string, add alphabetically small char at beginning to make it sort correctly @@ -209,7 +228,7 @@ _for do { // Sort alphabetically, find the previously selected item, select it again and reset text to original text if (_right) then { - _panel lnbSort [1, false]; + _panel lnbSort [1, _sortDirection == ASCENDING]; _for do { _item = _panel lnbData [_i, 0]; @@ -225,7 +244,7 @@ if (_right) then { }; }; } else { - lbSort [_panel, "ASC"]; + lbSort [_panel, ["DESC", "ASC"] select _sortDirection]; _for do { _item = _panel lbData _i; diff --git a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf index 3e0a0646f18..f60b82ba27a 100644 --- a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf @@ -28,7 +28,11 @@ private _indexCurrentItems = -1; case IDX_LOADOUT_BINO: { _x params [["_weapon", ""], ["_muzzle", ""], ["_flashlight", ""], ["_optics", ""], ["_primaryMagazine", []], ["_secondaryMagazine", []], ["_bipod", ""]]; - _weapon = _weapon call FUNC(baseWeapon); + // Find baseweapon of weapon + if (_weapon != "") then { + _weapon = _weapon call FUNC(baseWeapon); + }; + _isWeapon = _forEachIndex != IDX_LOADOUT_BINO; // If bino, add it in a different place than regular weapons @@ -38,7 +42,7 @@ private _indexCurrentItems = -1; // Add weapon attachments { - (GVAR(currentItems) select _indexCurrentItems) set [[2, 1, 0, 3] select _forEachIndex, _x]; + (GVAR(currentItems) select _indexCurrentItems) set [[2, 1, 0, 3] select _forEachIndex, if (_x != "") then {_x call FUNC(baseWeapon)} else {_x}]; } forEach [_optics, _flashlight, _muzzle, _bipod]; // Add magazines diff --git a/addons/arsenal/functions/fnc_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf index 99e7dc2465a..04e93445ae1 100644 --- a/addons/arsenal/functions/fnc_updateRightPanel.sqf +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -18,13 +18,14 @@ params ["_control", "_container", "_hasItems"]; private _loadRemaining = maxLoad _container - loadAbs _container; +private _rightPanelCache = uiNamespace getVariable [QGVAR(rightPanelCache), createHashMap]; private _mass = -1; private _color = []; // Grey out items that are too big to fit in remaining space of the container for "_row" from 0 to (lnbSize _control select 0) - 1 do { - _mass = _control getVariable (_control lnbData [_row, 0]); + _mass = _rightPanelCache getOrDefault [_control lnbData [_row, 0], 0]; // Lower alpha on color for items that can't fit _color = [1, 1, 1, [0.25, 1] select (_mass <= _loadRemaining)]; @@ -51,6 +52,6 @@ private _curSel = lnbCurSelRow _control; // Disable '+' button if item is unique or too big to fit in remaining space if (_curSel != -1) then { private _plusButtonCtrl = _display displayCtrl IDC_arrowPlus; - _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_control getVariable (_control lnbData [_curSel, 0])) > _loadRemaining}); + _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_rightPanelCache getOrDefault [_control lnbData [_curSel, 0], 0]) > _loadRemaining}); _plusButtonCtrl ctrlCommit FADE_DELAY; }; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 6e089e143b6..446ab339ee3 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -21,8 +21,11 @@ GVAR(virtualItems) set [IDX_VIRT_UNIQUE_EXPLOSIVES, []]; GVAR(virtualItems) set [IDX_VIRT_UNIQUE_ATTACHMENTS, [[], [], [], []]]; GVAR(virtualItems) set [IDX_VIRT_UNIQUE_BACKPACKS, []]; GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GOGGLES, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_UNKNOWN_ITEMS, []]; -private _configItems = uiNamespace getVariable QGVAR(configItems); +private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; +private _configItemsFlat = uiNamespace getVariable [QGVAR(configItemsFlat), []]; +private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; @@ -104,6 +107,15 @@ private _isWeapon = false; ): { (GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) pushBackUnique _x; }; + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + case ( + _isMagazine && + {_x in _magazineMiscItems} && + {!(_x in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS))} && + {_x in (_configItems select IDX_VIRT_MISC_ITEMS)} + ): { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) pushBackUnique _x; + }; // Backpacks case (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1): { (GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) pushBackUnique _x; @@ -112,5 +124,12 @@ private _isWeapon = false; case (isClass (_cfgGlasses >> _x)): { (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) pushBackUnique _x; }; + // Unknown + default { + // Don't add items that are part of the arsenal + if !(_x in _configItemsFlat) then { + (GVAR(virtualItems) select IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) pushBackUnique _x; + }; + }; }; -} forEach ([GVAR(center)] call EFUNC(common,uniqueItems)); +} forEach (keys ([GVAR(center), 0, 3, 3, 3, false] call EFUNC(common,uniqueUnitItems))); // Get all items from unit diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index b8cd915fa0a..4bb6ce4deaa 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -31,6 +31,7 @@ private _cfgGlasses = configFile >> "CfgGlasses"; private _weaponsArray = GVAR(virtualItems) select IDX_VIRT_WEAPONS; private _accsArray = GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS; +private _name = ""; private _nullItemsAmount = 0; private _unavailableItemsAmount = 0; private _nullItemsList = []; @@ -41,7 +42,7 @@ private _fnc_toConfigCase = { _this apply { if (_x isEqualType "") then { if (_x != "") then { - private _name = _x call EFUNC(common,getConfigName); + _name = _x call EFUNC(common,getConfigName); // If item doesn't exist in config, "" is returned // Just return unaltered item name in that case, so it can be documented as being unavailable @@ -79,6 +80,9 @@ private _fnc_weaponCheck = { if (_x != "") then { // Check if item exists if (isClass (_cfgWeapons >> _x)) then { + // Get base weapon + _x = _x call FUNC(baseWeapon); + // Check if item is available in arsenal if !( // Weapon class name is at the very start of the array @@ -176,7 +180,8 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do if !( _item in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) || {_item in (GVAR(virtualItems) select IDX_VIRT_GRENADES)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES)} + {_item in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES)} || + {_item in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS)} ) then { _unavailableItemsList pushBackUnique _item; ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index 9e887949f54..ae1a7e9abf4 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -1483,5 +1483,11 @@ Сохранить эмблему Guardar Insignia + + Descending + + + Ascending + diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index 1bd6c9909ba..fc130f1b8bb 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -519,15 +519,24 @@ class GVAR(display) { idc = IDC_sortLeftTab; x = QUOTE(safezoneX + 13 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); - w = QUOTE(80 * GRID_W); + w = QUOTE(40 * GRID_W); h = QUOTE(6 * GRID_H); onLBSelChanged = QUOTE(_this call FUNC(sortPanel)); sizeEx = QUOTE(5 * GRID_H); }; + class sortLeftTabDirection: sortLeftTab { + idc = IDC_sortLeftTabDirection; + x = QUOTE(safezoneX + 53 * GRID_W); + w = QUOTE(40 * GRID_W); + }; class sortRightTab: sortLeftTab { idc = IDC_sortRightTab; x = QUOTE(safezoneX + safezoneW - 93 * GRID_W); }; + class sortRightTabDirection: sortLeftTabDirection { + idc = IDC_sortRightTabDirection; + x = QUOTE(safezoneX + safezoneW - 53 * GRID_W); + }; class leftSearchbar: ctrlEdit { idc = IDC_leftSearchbar; onSetFocus = QUOTE(GVAR(leftSearchbarFocus) = true); diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index b116548c125..341c68dd872 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -188,6 +188,7 @@ PREP(toNumber); PREP(unhideUnit); PREP(uniqueElements); PREP(uniqueItems); +PREP(uniqueUnitItems); PREP(unloadPerson); PREP(unloadPersonLocal); PREP(unloadUnitWeapon); diff --git a/addons/common/functions/fnc_getAddon.sqf b/addons/common/functions/fnc_getAddon.sqf index acdd3f689b4..45320b27aba 100644 --- a/addons/common/functions/fnc_getAddon.sqf +++ b/addons/common/functions/fnc_getAddon.sqf @@ -17,23 +17,14 @@ params ["_config"]; -// Check if item is cached -private _addon = (uiNamespace getVariable QGVAR(addonCache)) get _config; +(uiNamespace getVariable QGVAR(addonCache)) getOrDefaultCall [_config, { + private _addons = configSourceAddonList _config; -if (!isNil "_addon") exitWith { - _addon -}; - -private _addons = configSourceAddonList _config; - -// Return first addon -_addon = if (_addons isNotEqualTo []) then { - (configSourceModList (configfile >> "CfgPatches" >> _addons select 0)) param [0, ""] -} else { - // If nothing found at all, return "" - "" -}; - -(uiNamespace getVariable QGVAR(addonCache)) set [_config, _addon]; - -_addon + // Return first addon + if (_addons isNotEqualTo []) then { + (configSourceModList (configfile >> "CfgPatches" >> _addons select 0)) param [0, ""] + } else { + // If nothing found at all, return "" + "" + } +}, true] diff --git a/addons/common/functions/fnc_getConfigName.sqf b/addons/common/functions/fnc_getConfigName.sqf index e04b855b302..80aa9549d6c 100644 --- a/addons/common/functions/fnc_getConfigName.sqf +++ b/addons/common/functions/fnc_getConfigName.sqf @@ -17,26 +17,14 @@ params ["_className"]; -_className = toLower _className; +(uiNamespace getVariable QGVAR(configNames)) getOrDefaultCall [toLower _className, { + private _config = configNull; -// Check if item is cached -private _configName = (uiNamespace getVariable QGVAR(configNames)) get _className; + { + _config = configFile >> _x >> _className; -if (!isNil "_configName") exitWith { - _configName -}; + if (isClass _config) exitWith {}; + } forEach ["CfgWeapons", "CfgMagazines", "CfgGlasses", "CfgVehicles", "CfgVoice", "CfgUnitInsignia"]; -private _config = configNull; - -{ - _config = configFile >> _x >> _className; - - if (isClass _config) exitWith {}; -} forEach ["CfgWeapons", "CfgMagazines", "CfgGlasses", "CfgVehicles", "CfgVoice", "CfgUnitInsignia"]; - -_configName = configName _config; - -// Save, regardless of its existence -(uiNamespace getVariable QGVAR(configNames)) set [_className, _configName]; - -_configName + configName _config +}, true] diff --git a/addons/common/functions/fnc_uniqueUnitItems.sqf b/addons/common/functions/fnc_uniqueUnitItems.sqf new file mode 100644 index 00000000000..4c1532d9380 --- /dev/null +++ b/addons/common/functions/fnc_uniqueUnitItems.sqf @@ -0,0 +1,47 @@ +#include "script_component.hpp" +/* + * Author: johnb43 + * Returns list of items (including magazines, backpacks and other) in a unit's inventory. + * Number definition: 0: Do not return value, 1: Return container only, 2: Return container and content, 3: Return content only + * + * Arguments: + * 0: Unit + * 1: Weapon items (default: 2) + * 2: Uniform items (default: 2) + * 3: Vest items (default: 2) + * 4: Backpack items (default: 2) + * 2: Assigned items (default: true) + * + * Return Value: + * Items + * + * Example: + * [player] call ace_common_fnc_uniqueUnitItems + * + * Public: Yes + */ + +params ["_unit", ["_weaponItems", 2, [0]], ["_uniformItems", 2, [0]], ["_vestItems", 2, [0]], ["_backpackItems", 2, [0]], ["_assignedItems", true, [false]]]; + +// 'uniqueUnitItems' can take any number, number other than 0 and 1 have the same effect as the number '2' +private _uniqueUnitItems = uniqueUnitItems [_unit, _weaponItems, _uniformItems, _vestItems, _backpackItems, _assignedItems]; + +private _amount = 0; + +// Remove unit's uniform, vest and backpack if there aren't in the containers themselves if necessary +{ + _x params ["_container", "_filter"]; + + if ((_filter == 3) && {_container != ""}) then { + _amount = _uniqueUnitItems get _container; + + // Delete item from hashmap if it's the only one + if (_amount == 1) then { + _uniqueUnitItems deleteAt _container; + } else { + _uniqueUnitItems set [_container, _amount - 1]; + }; + }; +} forEach [[uniform _unit, _uniformItems], [vest _unit, _vestItems], [backpack _unit, _backpackItems]]; + +_uniqueUnitItems diff --git a/addons/laserpointer/CfgWeapons.hpp b/addons/laserpointer/CfgWeapons.hpp index 6afa29a3440..e89cd244d9c 100644 --- a/addons/laserpointer/CfgWeapons.hpp +++ b/addons/laserpointer/CfgWeapons.hpp @@ -32,6 +32,7 @@ class CfgWeapons { picture = "\A3\weapons_F\Data\UI\gear_accv_pointer_CA.paa"; model = "\A3\weapons_f\acc\accv_pointer_F"; descriptionShort = CSTRING(Description); + baseWeapon = "acc_pointer_IR"; class ItemInfo: InventoryFlashLightItem_Base_F { mass = 6; @@ -82,6 +83,7 @@ class CfgWeapons { _generalMacro = "ACE_acc_pointer_green"; scope = 1; displayName = CSTRING(green); + baseWeapon = "ACE_acc_pointer_green"; }; class ACE_acc_pointer_green: ACE_acc_pointer_red { @@ -95,5 +97,6 @@ class CfgWeapons { _generalMacro = "ACE_acc_pointer_green"; scope = 2; displayName = CSTRING(green); + baseWeapon = "ACE_acc_pointer_green"; }; }; diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index ee580e255ad..419dcd4245c 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -87,7 +87,7 @@ Example: 1 | Items | Array of strings or boolean | Required 2 | Add globally | Boolean | Optional (default: `false`) -Passing an array of strings (class names) will add each one of those items to the specified box, passing true will add ALL items that are compatible with ACE Arsenal (the sorting is done on game startup). +Passing an array of strings (class names) will add each one of those items to the specified box, passing true will add ALL items that are compatible with ACE Arsenal (the sorting is done on game startup). Faces, voices and insignia can't be added via this function. Examples: - `[_box, ["item1", "item2", "itemN"]] call ace_arsenal_fnc_addVirtualItems` @@ -103,7 +103,7 @@ Examples: 1 | Items | Array of strings or boolean | Required 2 | Remove globally | Boolean | Optional (default: `false`) -Like adding virtual items, passing an array of string (class names) will remove each ones of those items, however passing true will remove all virtual items and also remove the interaction to access ACE Arsenal. +Like adding virtual items, passing an array of string (class names) will remove each ones of those items, however passing true will remove all virtual items and also remove the interaction to access ACE Arsenal. Faces, voices and insignia can't be removed via this function. Examples: - `[_box, ["item1", "item2", "itemN"]] call ace_arsenal_fnc_removeVirtualItems` @@ -135,10 +135,12 @@ Examples: ACE Arsenal has 2 new config entries for items: - `ace_arsenal_hide`: `0`(shown) or `1` (hidden), used to hide items from ACE Arsenal or `-1` (forced show), for magazines. -- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout. Supports configs in "CfgWeapons", "CfgMagazines" and "CfgVehicles". Item that replaces must be of the same config type as the original item. +- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout and displaying it in the arsenal. Supports configs in "CfgWeapons" (e.g. Maps, Compasses, Watches, GPS / UAV Terminals, Radios, NVGs, Uniforms, Vests - however no Primary, Secondary, Handgun or Launcher weapons are supported), "CfgMagazines" (any magazine) and "CfgVehicles" (e.g. Backpacks). Item that replaces must be of the same config type as the original item. Both of them are optional. +- `baseWeapon`: Class name that is used to display an item in the arsenal. This property can be applied to any weapon or weapon attachment in "CfgWeapons". + ## 4. Default loadouts ### 4.1 Adding default loadouts via 3DEN From 8a4a08f30e1e04ed22e3408af13965e7322f5bc8 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 9 Jul 2023 20:58:39 +0200 Subject: [PATCH 11/24] More fixes and tweaks - Converted the arsenal to partially work with hashmaps instead of arrays (for configItems and virtualItems, currentItems is still an array). - Because of the above, performance of FUNC(addVirtualItems) and FUNC(removeVirtualItems) has improved immensely. - Sorting now caches results, reducing repeated sorting times drastically. - CBA disposable launchers are handled differently now: Within the arsenal, you can change weapon attachments on disposable launchers, but you can't change their magazines (primary or secondary). Item info on the right and the stats show correct information. - FUNC(addSort) now checks if the new sorting method already exists and doesn't add it if it does. - FUNC(removeSort) now exists. You can't remove the default sort type (alphabetically) to avoid problems with the arsenal. - Both FUNC(addStat) and FUNC(compileStats) actually taken priority into account now. Because of that priority on several stats needed to be tweaked. - FUNC(removeStat) ensures that there are no gaps within the stat array (so if there is an empty spot in the stats page, it's because there is a stat, but the condition for it being shown hasn't been met). --- addons/arsenal/ACE_Arsenal_Stats.hpp | 13 +- addons/arsenal/XEH_PREP.hpp | 1 + addons/arsenal/XEH_postInit.sqf | 2 - addons/arsenal/XEH_preInit.sqf | 1 + addons/arsenal/XEH_preStart.sqf | 1 + addons/arsenal/config.cpp | 2 +- addons/arsenal/defines.hpp | 40 --- addons/arsenal/functions/fnc_addSort.sqf | 42 ++- addons/arsenal/functions/fnc_addStat.sqf | 100 ++++-- .../arsenal/functions/fnc_addVirtualItems.sqf | 252 ++++----------- .../functions/fnc_attributeAddCompatible.sqf | 43 ++- .../functions/fnc_attributeAddItems.sqf | 20 +- .../arsenal/functions/fnc_attributeClear.sqf | 10 +- .../arsenal/functions/fnc_attributeImport.sqf | 22 +- addons/arsenal/functions/fnc_buttonCargo.sqf | 6 +- addons/arsenal/functions/fnc_compileSorts.sqf | 39 ++- addons/arsenal/functions/fnc_compileStats.sqf | 145 +++++---- .../arsenal/functions/fnc_fillLeftPanel.sqf | 34 +-- .../arsenal/functions/fnc_fillRightPanel.sqf | 88 +++--- addons/arsenal/functions/fnc_handleStats.sqf | 52 ++-- .../arsenal/functions/fnc_onArsenalClose.sqf | 1 + .../arsenal/functions/fnc_onArsenalOpen.sqf | 90 ++++-- .../functions/fnc_onSelChangedLeft.sqf | 52 ++-- .../functions/fnc_onSelChangedRight.sqf | 27 +- addons/arsenal/functions/fnc_openBox.sqf | 41 ++- addons/arsenal/functions/fnc_removeSort.sqf | 54 ++++ addons/arsenal/functions/fnc_removeStat.sqf | 67 ++-- .../functions/fnc_removeVirtualItems.sqf | 81 +++-- .../fnc_replaceUniqueItemsLoadout.sqf | 100 +++--- addons/arsenal/functions/fnc_scanConfig.sqf | 96 +++--- addons/arsenal/functions/fnc_sortPanel.sqf | 25 +- .../functions/fnc_updateCurrentItemsList.sqf | 2 +- .../functions/fnc_updateUniqueItemsList.sqf | 90 +++--- .../arsenal/functions/fnc_verifyLoadout.sqf | 42 +-- addons/arsenal/ui/RscAttributes.hpp | 288 +++++++++--------- addons/ballistics/ACE_Arsenal_Stats.hpp | 2 +- addons/gforces/ACE_Arsenal_Stats.hpp | 2 +- addons/hearing/ACE_Arsenal_Stats.hpp | 2 +- docs/wiki/framework/arsenal-framework.md | 16 +- 39 files changed, 1086 insertions(+), 905 deletions(-) create mode 100644 addons/arsenal/functions/fnc_removeSort.sqf diff --git a/addons/arsenal/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp index 3528a7694b8..5fdd9cfa0d3 100644 --- a/addons/arsenal/ACE_Arsenal_Stats.hpp +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -13,7 +13,7 @@ class GVAR(stats) { }; class ACE_bananaPotassium: statBase { scope = 2; - displayName= CSTRING(statPotassium); + displayName = CSTRING(statPotassium); showBar = 1; barStatement = "1"; condition = QUOTE((configName (_this select 1)) == 'ACE_Banana'); @@ -21,7 +21,8 @@ class GVAR(stats) { }; class ACE_mass: statBase { scope = 2; - displayName= "$STR_a3_rscdisplayarsenal_stat_weight"; + priority = 1.5; + 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}}; @@ -30,7 +31,7 @@ class GVAR(stats) { scope = 2; priority = 5; stats[] = {"reloadTime"}; - displayName= "$STR_a3_rscdisplayarsenal_stat_rof"; + displayName = "$STR_a3_rscdisplayarsenal_stat_rof"; showBar = 1; showText = 1; barStatement = QUOTE([ARR_3((_this select 0) select 0, _this select 1, [ARR_2([ARR_2(-1.4, 0.31)], [ARR_2(1, 0.01)])])] call FUNC(statBarStatement_rateOfFIre)); @@ -50,7 +51,7 @@ class GVAR(stats) { }; class ACE_maxZeroing: statBase { scope = 2; - priority = 3; + priority = 3.2; stats[] = {"maxZeroing"}; displayName = "$STR_a3_rscdisplayarsenal_stat_range"; showBar = 1; @@ -59,7 +60,7 @@ class GVAR(stats) { }; class ACE_impact: statBase { scope = 2; - priority = 2; + priority = 3.1; stats[] = {"hit", "initSpeed"}; displayName = "$STR_a3_rscdisplayarsenal_stat_impact"; showBar = 1; @@ -76,7 +77,7 @@ class GVAR(stats) { }; class ACE_scopeVisionMode: statBase { scope = 2; - priority = 1; + priority = 1.6; displayName = CSTRING(statVisionMode); showText = 1; textStatement = QUOTE(call FUNC(statTextStatement_scopeVisionMode)); diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index 84ed1e964df..d695861f404 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -59,6 +59,7 @@ PREP(open3DEN); PREP(openBox); PREP(portVALoadouts); PREP(removeBox); +PREP(removeSort); PREP(removeStat); PREP(removeVirtualItems); PREP(replaceUniqueItemsLoadout); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index 93027b84719..c047f4800b9 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -17,13 +17,11 @@ GVAR(lastSortDirectionRight) = DESCENDING; [QGVAR(broadcastFace), { params ["_unit", "_face"]; - _unit setFace _face; }] call CBA_fnc_addEventHandler; [QGVAR(broadcastVoice), { params ["_unit", "_voice"]; - _unit setSpeaker _voice; }] call CBA_fnc_addEventHandler; diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 1982f15780f..25f0b22363e 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -59,6 +59,7 @@ PREP_RECOMPILE_END; _this call FUNC(handleStats); }] call CBA_fnc_addEventHandler; +// Compile sorts and stats call FUNC(compileStats); call FUNC(compileSorts); diff --git a/addons/arsenal/XEH_preStart.sqf b/addons/arsenal/XEH_preStart.sqf index 84411203073..7e561340104 100644 --- a/addons/arsenal/XEH_preStart.sqf +++ b/addons/arsenal/XEH_preStart.sqf @@ -8,5 +8,6 @@ uiNamespace setVariable [QGVAR(baseWeaponNameCache), createHashMap]; // Caches for names, pictures, mod icons uiNamespace setVariable [QGVAR(addListBoxItemCache), createHashMap]; uiNamespace setVariable [QGVAR(rightPanelCache), createHashMap]; +uiNamespace setVariable [QGVAR(sortCache), createHashMap]; call FUNC(scanConfig); diff --git a/addons/arsenal/config.cpp b/addons/arsenal/config.cpp index e491065480d..733328b2414 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", "Brett Mayson"}; + authors[] = {"alganthe", "mharis001", "Brett Mayson", "johnb43"}; url = ECSTRING(main,URL); VERSION_CONFIG; }; diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index d9275aad45e..220a3d82c5e 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -205,46 +205,6 @@ #define IDX_CAT_EXPLOSIVES 22 #define IDX_CAT_MISC_ITEMS 23 -// Weapons 0 [primary, handgun, secondary] -// Weapon attachements 1 [optics, flashlight, muzzle, bipod] -// Magazines 2 -// Headgear 3 -// Uniform 4 -// Vest 5 -// Backpacks 6 -// Goggles 7 -// NVGs 8 -// Binoculars 9 -// Map 10 -// Compass 11 -// Radio slot 12 -// Watch slot 13 -// Comms slot (GPS, UAV terminals) 14 -// Grenades (WeaponThrow) 15 -// Explosives (WeaponPut) 16 -// InventoryItems 17 -#define EMPTY_VIRTUAL_ARSENAL\ -[\ - [[],[],[]],\ - [[],[],[],[]],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - [],\ - []\ -] - // Indexes of virtual items array #define IDX_VIRT_WEAPONS 0 #define IDX_VIRT_PRIMARY_WEAPONS 0 diff --git a/addons/arsenal/functions/fnc_addSort.sqf b/addons/arsenal/functions/fnc_addSort.sqf index cc116823399..7dac85af361 100644 --- a/addons/arsenal/functions/fnc_addSort.sqf +++ b/addons/arsenal/functions/fnc_addSort.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* - * Author: Brett Mayson - * Add a custom sorting method. + * Author: Brett Mayson, johnb43 + * Adds a custom sorting method. * * Arguments: * 0: Tabs to add sort to @@ -37,7 +37,8 @@ params [ ["_class", "", [""]], ["_title", "", [""]], ["_statement", {}, [{}]], - ["_condition", {true}, [{}]] + ["_condition", {true}, [{}]], + ["_overwrite", false, [false]] ]; _tabs params [ @@ -45,29 +46,46 @@ _tabs params [ ["_rightTabs", [], [[]]] ]; +// Compile sorts from config (in case this is called before preInit) call FUNC(compileSorts); -private _returnArray = []; +private _return = []; private _fnc_addToTabs = { - params ["_tabsList", "_tabsToAddTo", "_sideString"]; + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _sort = []; + private _sortName = ""; + private _currentTab = []; { - 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; + // Copy title, statement and condition + _sort = +_finalArray; + + // Make sort name + _sortName = [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; + _sort set [0, _sortName]; + + _currentTab = _tabsList select _x; + + // Find if there is an entry with same ID + if ((_currentTab findIf {(_x select 0) == _sortName}) == -1) then { + _currentTab pushBack _sort; + _return pushBack _sortName; + } else { + TRACE_1("A sort with this ID already exists", _sortName); + }; } forEach _tabsToAddTo; }; private _finalArray = ["", _title, _statement, _condition]; if (_leftTabs isNotEqualTo []) then { - [GVAR(sortListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; + [GVAR(sortListLeftPanel), _leftTabs, "L"] call _fnc_addToTabs; }; if (_rightTabs isNotEqualTo []) then { - [GVAR(sortListRightPanel), _rightTabs, "R", 1] call _fnc_addToTabs; + [GVAR(sortListRightPanel), _rightTabs, "R"] call _fnc_addToTabs; }; -_returnArray +_return diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf index 71831e656e8..d813974f406 100644 --- a/addons/arsenal/functions/fnc_addStat.sqf +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -1,7 +1,7 @@ #include "script_component.hpp" /* - * Author: Alganthe - * Add a stat to ACE Arsenal. + * Author: Alganthe, johnb43 + * Adds a stat to ACE Arsenal. * * Arguments: * 0: Tabs to add the stat to @@ -13,7 +13,7 @@ * 4: Show bar / show text bools * 4.0: Show bar (default: false) * 4.1: Show text (default: false) - * 5: Array of statements + * 5: Array of statements * 5.0: Bar code (default: {}) * 5.1: Text code (default: {}) * 5.2: Condition code (default: {true}) @@ -26,7 +26,7 @@ * [[[0, 1, 2], [7]], "scopeStat", ["scope"], "Scope", [false, true], [{}, { * params ["_statsArray", "_itemCfg"]; * getNumber (_itemCfg >> _statsArray select 0) - * }, {true}]] call ACE_arsenal_fnc_addStat + * }, {true}]] call ace_arsenal_fnc_addStat * * Public: Yes */ @@ -57,34 +57,44 @@ _statements params [ ["_condition", {true}, [{}]] ]; +// Compile stats from config (in case this is called before preInit) call FUNC(compileStats); -private _returnArray = []; +private _return = []; +private _changes = []; private _fnc_addToTabs = { - params ["_tabsList", "_tabsToAddTo", "_sideString", "_returnIndex"]; + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _statName = ""; + private _currentTab = []; + private _stat = []; { - private _currentTab = _tabsList select _x; - private _finalID = [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; + // Make stat name + _statName = [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""; + _currentTab = _tabsList select _x; - if ({{(_x select 0) == _finalID} count _x > 0} count _currentTab > 0) then { - TRACE_1("A stat with this ID already exists", _finalID); + // Find if there is an entry with same ID + if (_currentTab findIf {_x findIf {_x select 0 == _statName} != -1} != -1) then { + TRACE_1("A stat with this ID already exists", _statName); } else { - private _arrayToSave = +_finalArray; - _arrayToSave set [0, _finalID]; - _returnArray pushBack _finalID; + _stat = +_finalArray; + _stat set [0, _statName]; + + _index = _currentTab findIf {count _x < 5}; // 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; + if (_index != -1) then { + (_currentTab select _index) pushBack _stat; } else { - _currentTab pushBack [_arrayToSave]; + _currentTab pushBack [_stat]; }; + + _return pushBack _statName; + + // Store information, so that only tabs that were changed can be sorted again + _changes pushBackUnique [_x, _tabSide]; }; } forEach _tabsToAddTo; }; @@ -92,11 +102,55 @@ private _fnc_addToTabs = { private _finalArray = ["", _stats, _title, [_showBar, _showText], [_barStatement, _textStatement, _condition], _priority]; if (_leftTabs isNotEqualTo []) then { - [GVAR(statsListLeftPanel), _leftTabs, "L", 0] call _fnc_addToTabs; + [GVAR(statsListLeftPanel), _leftTabs, "L"] call _fnc_addToTabs; }; if (_rightTabs isNotEqualTo []) then { - [GVAR(statsListRightPanel), _rightTabs, "R", 1] call _fnc_addToTabs; + [GVAR(statsListRightPanel), _rightTabs, "R"] call _fnc_addToTabs; }; -_returnArray +private _statsFlat = []; +private _stats = []; +private _tabToChange = []; + +// Ensure priority is kept +{ + _x params ["_tab", "_tabSide"]; + + _tabToChange = if (_tabSide == "R") then { + GVAR(statsListRightPanel) + } else { + GVAR(statsListLeftPanel) + }; + + _statsFlat = []; + + // Get all stats of a tab into a single array + { + _statsFlat append _x; + } forEach (_tabToChange select _tab); + + // Put priority up front + { + reverse _x; + } forEach _statsFlat; + + // Sort numerically + _statsFlat sort false; + + // Put it back at the rear + { + reverse _x; + } forEach _statsFlat; + + _stats = []; + + // Group stats into groups of 5 + for "_index" from 0 to count _statsFlat - 1 step 5 do { + _stats pushBack (_statsFlat select [_index, _index + 5]); + }; + + _tabToChange set [_tab, _stats]; +} forEach _changes; + +_return diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index aae2f5c07b4..caff60bb7e2 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -23,33 +23,46 @@ params [["_object", objNull, [objNull]], ["_items", [], [true, []]], ["_global", if (isNull _object || {_items isEqualTo []}) exitWith {}; -private _cargo = _object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]; +private _cargo = _object getVariable QGVAR(virtualItems); + +if (isNil "_cargo") then { + _cargo = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; + + _cargo = createHashMapFromArray _cargo; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _cargo set [_index, createHashMap]; + }; +}; // If passed arguement is "true", add all items if (_items isEqualType true) then { if (_items) then { - private _weapons = _cargo select IDX_VIRT_WEAPONS; - private _weaponAttachments = _cargo select IDX_VIRT_ATTACHMENTS; - private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; + private _weapons = _cargo get IDX_VIRT_WEAPONS; + private _weaponAttachments = _cargo get IDX_VIRT_ATTACHMENTS; + private _configItems = uiNamespace getVariable QGVAR(configItems); // Add onto existing items, in case some items that were already added aren't available by default in the arsenal { - (_x select 0) append (_x select 1); - (_x select 2) set [_x select 3, (_x select 0) arrayIntersect (_x select 0)]; + (_x select 0) merge [_x select 1, true]; + (_x select 2) set [_x select 3, _x select 0]; } forEach [ - [_weapons select IDX_VIRT_PRIMARY_WEAPONS, _configItems select IDX_VIRT_WEAPONS select IDX_VIRT_PRIMARY_WEAPONS, _weapons, IDX_VIRT_PRIMARY_WEAPONS], - [_weapons select IDX_VIRT_SECONDARY_WEAPONS, _configItems select IDX_VIRT_WEAPONS select IDX_VIRT_SECONDARY_WEAPONS, _weapons, IDX_VIRT_SECONDARY_WEAPONS], - [_weapons select IDX_VIRT_HANDGUN_WEAPONS, _configItems select IDX_VIRT_WEAPONS select IDX_VIRT_HANDGUN_WEAPONS, _weapons, IDX_VIRT_HANDGUN_WEAPONS], - [_weaponAttachments select IDX_VIRT_OPTICS_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_OPTICS_ATTACHMENTS, _weaponAttachments, IDX_VIRT_OPTICS_ATTACHMENTS], - [_weaponAttachments select IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _weaponAttachments, IDX_VIRT_FLASHLIGHT_ATTACHMENTS], - [_weaponAttachments select IDX_VIRT_MUZZLE_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_MUZZLE_ATTACHMENTS, _weaponAttachments, IDX_VIRT_MUZZLE_ATTACHMENTS], - [_weaponAttachments select IDX_VIRT_BIPOD_ATTACHMENTS, _configItems select IDX_VIRT_ATTACHMENTS select IDX_VIRT_BIPOD_ATTACHMENTS, _weaponAttachments, IDX_VIRT_BIPOD_ATTACHMENTS] + [_weapons get IDX_VIRT_PRIMARY_WEAPONS, _configItems get IDX_VIRT_WEAPONS get IDX_VIRT_PRIMARY_WEAPONS, _weapons, IDX_VIRT_PRIMARY_WEAPONS], + [_weapons get IDX_VIRT_SECONDARY_WEAPONS, _configItems get IDX_VIRT_WEAPONS get IDX_VIRT_SECONDARY_WEAPONS, _weapons, IDX_VIRT_SECONDARY_WEAPONS], + [_weapons get IDX_VIRT_HANDGUN_WEAPONS, _configItems get IDX_VIRT_WEAPONS get IDX_VIRT_HANDGUN_WEAPONS, _weapons, IDX_VIRT_HANDGUN_WEAPONS], + [_weaponAttachments get IDX_VIRT_OPTICS_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_OPTICS_ATTACHMENTS, _weaponAttachments, IDX_VIRT_OPTICS_ATTACHMENTS], + [_weaponAttachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_FLASHLIGHT_ATTACHMENTS, _weaponAttachments, IDX_VIRT_FLASHLIGHT_ATTACHMENTS], + [_weaponAttachments get IDX_VIRT_MUZZLE_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_MUZZLE_ATTACHMENTS, _weaponAttachments, IDX_VIRT_MUZZLE_ATTACHMENTS], + [_weaponAttachments get IDX_VIRT_BIPOD_ATTACHMENTS, _configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_BIPOD_ATTACHMENTS, _weaponAttachments, IDX_VIRT_BIPOD_ATTACHMENTS] ]; // Add onto existing items, in case some items that were already added aren't available by default in the arsenal for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { - (_cargo select _index) append (_configItems select _index); - _cargo set [_index, (_cargo select _index) arrayIntersect (_cargo select _index)]; + (_cargo get _index) merge [_configItems get _index, true]; + _cargo set [_index, _cargo get _index]; }; }; } else { @@ -59,197 +72,50 @@ if (_items isEqualType true) then { // Remove any invalid/non-existing items _items = _items - [""]; - private _configItemInfo = ""; - private _simulationType = ""; - private _hasItemInfo = false; - private _config = configNull; + private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); - private _cfgWeapons = configFile >> "CfgWeapons"; - private _cfgMagazines = configFile >> "CfgMagazines"; - private _cfgVehicles = configFile >> "CfgVehicles"; - private _cfgGlasses = configFile >> "CfgGlasses"; + // Remove any items not found by the arsenal + _items = _items select {_x in _configItemsFlat}; - private _grenadeList = uiNamespace getVariable [QGVAR(grenadeCache), []]; - private _putList = uiNamespace getVariable [QGVAR(putCache), []]; - private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), createHashMap]; + private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); + private _configItems = uiNamespace getVariable QGVAR(configItems); // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 { - _configItemInfo = _cfgWeapons >> _x >> "ItemInfo"; - _simulationType = getText (_cfgWeapons >> _x >> "simulation"); - _hasItemInfo = isClass (_configItemInfo); - switch (true) do { - case (isClass (_cfgWeapons >> _x)): { - _config = _cfgWeapons >> _x; - - // Check if valid class - if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { - continue; - }; - - switch (true) do { - // Weapon attachments - case ( - _hasItemInfo && - {getNumber (_configItemInfo >> "type") in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]} && - {!(_x isKindOf ["CBA_MiscItem", _cfgWeapons])} - ): { - switch (getNumber (_configItemInfo >> "type")) do { - case TYPE_OPTICS: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); - }; - case TYPE_FLASHLIGHT: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); - }; - case TYPE_MUZZLE: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); - }; - case TYPE_BIPOD: { - ((_cargo select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS) pushBackUnique (_className call FUNC(baseWeapon)); - }; - }; - }; - // Headgear - case ( - _hasItemInfo && - {getNumber (_configItemInfo >> "type") == TYPE_HEADGEAR} - ): { - (_cargo select IDX_VIRT_HEADGEAR) pushBackUnique _x; - }; - // Uniforms - case ( - _hasItemInfo && - {getNumber (_configItemInfo >> "type") == TYPE_UNIFORM} - ): { - (_cargo select IDX_VIRT_UNIFORM) pushBackUnique _x; - }; - // Vests - case ( - _hasItemInfo && - {getNumber (_configItemInfo >> "type") == TYPE_VEST} - ): { - (_cargo select IDX_VIRT_VEST) pushBackUnique _x; - }; - // NVGs - case (_simulationType == "NVGoggles"): { - (_cargo select IDX_VIRT_NVG) pushBackUnique _x; - }; - // Binoculars - case ( - _simulationType == "Binocular" || - {_simulationType == "Weapon" && {getNumber (_config >> "type") == TYPE_BINOCULAR_AND_NVG}} - ): { - (_cargo select IDX_VIRT_BINO) pushBackUnique _x; - }; - // Maps - case (_simulationType == "ItemMap"): { - (_cargo select IDX_VIRT_MAP) pushBackUnique _x; - }; - // Compasses - case (_simulationType == "ItemCompass"): { - (_cargo select IDX_VIRT_COMPASS) pushBackUnique _x; - }; - // Radios - case (_simulationType == "ItemRadio"): { - (_cargo select IDX_VIRT_RADIO) pushBackUnique _x; - }; - // Watches - case (_simulationType == "ItemWatch"): { - (_cargo select IDX_VIRT_WATCH) pushBackUnique _x; - }; - // GPS and UAV Terminals - case ( - _simulationType == "ItemGPS" || - {_hasItemInfo && - {getNumber (_configItemInfo >> "type") == TYPE_UAV_TERMINAL}} - ): { - (_cargo select IDX_VIRT_COMMS) pushBackUnique _x; - }; - // Weapons, at the bottom to avoid adding binos - case ( - isClass (_config >> "WeaponSlotsInfo") && - {getNumber (_config >> "type") != TYPE_BINOCULAR_AND_NVG} - ): { - switch (getNumber (_config >> "type")) do { - case TYPE_WEAPON_PRIMARY: { - ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_x call FUNC(baseWeapon)); - }; - case TYPE_WEAPON_HANDGUN: { - ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_x call FUNC(baseWeapon)); - }; - case TYPE_WEAPON_SECONDARY: { - ((_cargo select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_x call FUNC(baseWeapon)); - }; - }; - }; - // Misc. items - case ( - _hasItemInfo && - {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD] && - {_x isKindOf ["CBA_MiscItem", _cfgWeapons]}} || - {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {getText (_config >> "simulation") == "ItemMineDetector"} - ): { - (_cargo select IDX_VIRT_MISC_ITEMS) pushBackUnique _x; - }; - }; + // Weapons + case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) set [_x call FUNC(baseWeapon), nil]; }; - case (isClass (_cfgMagazines >> _x)): { - _config = _cfgMagazines >> _x; - - // Check if valid class - if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { - continue; - }; - - // Check what type the magazine actually is - switch (true) do { - // "Misc. items" magazines (e.g. spare barrels, intel, photos) - case (_x in _magazineMiscItems): { - (_cargo select IDX_VIRT_MISC_ITEMS) pushBackUnique _x; - }; - // Grenades - case (_x in _grenadeList): { - (_cargo select IDX_VIRT_GRENADES) pushBackUnique _x; - }; - // Explosives - case (_x in _putList): { - (_cargo select IDX_VIRT_EXPLOSIVES) pushBackUnique _x; - }; - // Primary, handgun & secondary weapon magazines, and magazines that are forced with "ace_arsenal_hide = -1" - case ( - getNumber (_config >> QGVAR(hide)) == -1 || - {getNumber (_config >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL]} - ): { - (_cargo select IDX_VIRT_ITEMS_ALL) pushBackUnique _x; - }; - }; + case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) set [_x call FUNC(baseWeapon), nil]; + }; + case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) set [_x call FUNC(baseWeapon), nil]; }; - // Backpacks - case (isClass (_cfgVehicles >> _x)): { - _config = _cfgVehicles >> _x; - - // Check if valid class - if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { - continue; - }; - if (getNumber (_config >> "isBackpack") == 1) then { - (_cargo select IDX_VIRT_BACKPACK) pushBackUnique _x; - }; + // Weapon attachments + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + }; + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + }; + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + }; + case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; }; - // Goggles - case (isClass (_cfgGlasses >> _x)): { - _config = _cfgGlasses >> _x; - // Check if valid class - if !((if (isNumber (_config >> "scopeArsenal")) then {getNumber (_config >> "scopeArsenal") == 2 && {getNumber (_config >> "scope") > 0}} else {getNumber (_config >> "scope") == 2}) && {getNumber (_config >> QGVAR(hide)) != 1}) then { - continue; + // Other + default { + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + if (_x in (_configItems get _index)) exitWith { + (_cargo get _index) set [_x, nil]; + }; }; - - (_cargo select IDX_VIRT_GOGGLES) pushBackUnique _x; }; }; } forEach _items; diff --git a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf index 318a4585c16..88e5c55ec17 100644 --- a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf +++ b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf @@ -23,38 +23,61 @@ private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CAT // Exit if selected category is not attachments or magazines if !(_category in [IDX_CAT_OPTICS_ATTACHMENTS, IDX_CAT_FLASHLIGHT_ATTACHMENTS, IDX_CAT_MUZZLE_ATTACHMENTS, IDX_CAT_BIPOD_ATTACHMENTS, IDX_CAT_ITEMS_ALL]) exitWith {}; -private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; +private _configItems = uiNamespace getVariable QGVAR(configItems); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems"]; // Get list of all weapons in attribute items -private _attributeWeapons = _attributeItems arrayIntersect (flatten (_configItems select IDX_VIRT_WEAPONS)); +private _attributeWeapons = []; -// Add compatible attachments or magazines to attribute -private _itemsToAdd = []; +{ + _attributeWeapons append (_attributeItems arrayIntersect (keys _y)); +} forEach (_configItems get IDX_VIRT_WEAPONS); + +private _itemsToAdd = createHashMap; +// Add compatible attachments or magazines to attribute if (_category == IDX_CAT_ITEMS_ALL) then { + // Add compatible attachments or magazines to attribute + private _compatibleMagazines = createHashMap; + // Get all compatible magazines for weapons { - _itemsToAdd append (compatibleMagazines _x); + _compatibleMagazines insert [true, compatibleMagazines _x, []]; } forEach _attributeWeapons; - _itemsToAdd = _itemsToAdd arrayIntersect (_configItems select IDX_VIRT_ITEMS_ALL); + // Check if magazines are in configItems + { + if (_x in (_configItems get IDX_VIRT_ITEMS_ALL)) then { + _itemsToAdd set [_x, nil]; + }; + } forEach _compatibleMagazines; } else { private _attachmentCategory = _category - 4; private _filter = ["optic", "pointer", "muzzle", "bipod"] select _attachmentCategory; + private _compatibleItems = createHashMap; // CBA_fnc_compatibleItems returns config case sensitive names { - _itemsToAdd append ([_x, _filter] call CBA_fnc_compatibleItems); + _compatibleItems insert [true, [_x, _filter] call CBA_fnc_compatibleItems, []]; } forEach _attributeWeapons; - _itemsToAdd = _itemsToAdd arrayIntersect (flatten (_configItems select IDX_VIRT_ATTACHMENTS)); + // Check if attachments are in configItems + { + if ( + _x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_OPTICS_ATTACHMENTS) || + {_x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || + {_x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_MUZZLE_ATTACHMENTS)} || + {_x in (_configItems get IDX_VIRT_ATTACHMENTS get IDX_VIRT_BIPOD_ATTACHMENTS)} + ) then { + _itemsToAdd set [_x, nil]; + }; + } forEach _compatibleItems; }; // Only take items that can be found by default in the arsenal -_attributeItems append _itemsToAdd; -_attributeValue set [0, _attributeItems arrayIntersect _attributeItems]; +_attributeItems insert [-1, keys _itemsToAdd, true]; +_attributeValue set [0, _attributeItems]; // Refresh the list for new items [_controlsGroup] call FUNC(attributeAddItems); diff --git a/addons/arsenal/functions/fnc_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf index 555b1d3fa98..a0409a8cab9 100644 --- a/addons/arsenal/functions/fnc_attributeAddItems.sqf +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -20,8 +20,8 @@ params ["_controlsGroup"]; private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY); private _filter = toLower ctrlText (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR); -private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; -private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; +private _configItems = uiNamespace getVariable QGVAR(configItems); +private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue params ["_attributeItems", "_attributeMode"]; @@ -48,11 +48,11 @@ if (_category == IDX_CAT_ALL) exitWith { // Get appropriate config for each item (different since items can be from any category) _config = switch (true) do { case (_x in _magazineMiscItems); - case (_x in (_configItems select IDX_VIRT_ITEMS_ALL)); - case (_x in (_configItems select IDX_VIRT_GRENADES)); - case (_x in (_configItems select IDX_VIRT_EXPLOSIVES)): {_cfgMagazines >> _x}; - case (_x in (_configItems select IDX_VIRT_BACKPACK)): {_cfgVehicles >> _x}; - case (_x in (_configItems select IDX_VIRT_GOGGLES)): {_cfgGlasses >> _x}; + case (_x in (_configItems get IDX_VIRT_ITEMS_ALL)); + case (_x in (_configItems get IDX_VIRT_GRENADES)); + case (_x in (_configItems get IDX_VIRT_EXPLOSIVES)): {_cfgMagazines >> _x}; + case (_x in (_configItems get IDX_VIRT_BACKPACK)): {_cfgVehicles >> _x}; + case (_x in (_configItems get IDX_VIRT_GOGGLES)): {_cfgGlasses >> _x}; default {_cfgWeapons >> _x}; }; @@ -75,15 +75,15 @@ if (_category == IDX_CAT_ALL) exitWith { private _categoryItems = switch (true) do { // Weapons case (_category < IDX_CAT_OPTICS_ATTACHMENTS): { - _configItems select IDX_VIRT_WEAPONS select (_category - 1) + (_configItems get IDX_VIRT_WEAPONS) get (_category - 1) }; // Weapon attachments case (_category < IDX_CAT_ITEMS_ALL): { - _configItems select IDX_VIRT_ATTACHMENTS select (_category - 4) + (_configItems get IDX_VIRT_ATTACHMENTS) get (_category - 4) }; // Other default { - _configItems select (_category - 6) + _configItems get (_category - 6) }; }; diff --git a/addons/arsenal/functions/fnc_attributeClear.sqf b/addons/arsenal/functions/fnc_attributeClear.sqf index 24156810f3e..72f00a7bdc3 100644 --- a/addons/arsenal/functions/fnc_attributeClear.sqf +++ b/addons/arsenal/functions/fnc_attributeClear.sqf @@ -27,23 +27,23 @@ if (_category == IDX_CAT_ALL) then { _attributeValue set [0, []]; } else { // Find category items and remove from list - private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; + private _configItems = uiNamespace getVariable QGVAR(configItems); private _categoryItems = switch (true) do { // Weapons case (_category < IDX_CAT_OPTICS_ATTACHMENTS): { - _configItems select IDX_VIRT_WEAPONS select (_category - 1) + (_configItems get IDX_VIRT_WEAPONS) get (_category - 1) }; // Weapon attachments case (_category < IDX_CAT_ITEMS_ALL): { - _configItems select IDX_VIRT_ATTACHMENTS select (_category - 4) + (_configItems get IDX_VIRT_ATTACHMENTS) get (_category - 4) }; // Other default { - _configItems select (_category - 6) + _configItems get (_category - 6) }; }; - _attributeValue set [0, (_attributeValue select 0) - _categoryItems]; + _attributeValue set [0, (_attributeValue select 0) select {!(_x in _categoryItems)}]; }; // Refresh the list after clear diff --git a/addons/arsenal/functions/fnc_attributeImport.sqf b/addons/arsenal/functions/fnc_attributeImport.sqf index 878a5e3b9ea..d891dae0b8b 100644 --- a/addons/arsenal/functions/fnc_attributeImport.sqf +++ b/addons/arsenal/functions/fnc_attributeImport.sqf @@ -32,26 +32,8 @@ _importList = _importList apply {_x call EFUNC(common,getConfigName)}; _importList = _importList - [""]; // Ensure imported items are in scanned config array -private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; -private _configItemsFlat = _configItems select [2, 16]; -_configItemsFlat append (_configItems select IDX_VIRT_WEAPONS); -_configItemsFlat append (_configItems select IDX_VIRT_ATTACHMENTS); - -private _filteredList = []; -private _intersection = []; - -{ - // Find common entries - _intersection = _x arrayIntersect _importList; - - _filteredList append _intersection; - - // Remove found entries, to reduce input array size - _importList = _importList - _intersection; - - // Quit if nothing is left to import - if (_importList isEqualTo []) exitWith {}; -} forEach _configItemsFlat; +private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); +private _filteredList = _importList select {_x in _configItemsFlat}; private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]]; _attributeValue set [0, _filteredList]; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index ca88125cff5..a73e5cd8d2f 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -38,7 +38,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; } else { // Backpacks need special command to be removed - if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) select IDX_VIRT_BACKPACK)}) then { + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) get IDX_VIRT_BACKPACK)}) then { [uniformContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; } else { for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { @@ -66,7 +66,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; } else { // Backpacks need special command to be removed - if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) select IDX_VIRT_BACKPACK)}) then { + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) get IDX_VIRT_BACKPACK)}) then { [vestContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; } else { for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { @@ -94,7 +94,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; } else { // Backpacks need special command to be removed - if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) select IDX_VIRT_BACKPACK)}) then { + if (_isUnique && {_item in ((uiNamespace getVariable QGVAR(configItems)) get IDX_VIRT_BACKPACK)}) then { [backpackContainer GVAR(center), _item, [1, 5] select GVAR(shiftState)] call CBA_fnc_removeBackpackCargo; } else { for "_i" from 1 to ([1, 5] select GVAR(shiftState)) do { diff --git a/addons/arsenal/functions/fnc_compileSorts.sqf b/addons/arsenal/functions/fnc_compileSorts.sqf index 613843e27f4..d38cbe6b2ef 100644 --- a/addons/arsenal/functions/fnc_compileSorts.sqf +++ b/addons/arsenal/functions/fnc_compileSorts.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Brett Mayson + * Author: Brett Mayson, johnb43 * Create the internal sort arrays when needed for the first time. * * Arguments: @@ -15,12 +15,19 @@ if (!isNil QGVAR(sortListLeftPanel)) exitWith {}; private _fnc_addToTabs = { - params ["_tabsList", "_tabsToAddTo", "_sideString"]; + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; + + private _sort = []; { - private _arrayToSave = +_finalArray; - _arrayToSave set [0, [_class, _sideString, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; - (_tabsList select _x) pushBack _arrayToSave; + // Copy title, statement and condition + _sort = +_finalArray; + + // Make sort name + _sort set [0, [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; + + // No duplicates are possible here + (_tabsList select _x) pushBack _sort; } forEach _tabsToAddTo; }; @@ -57,15 +64,17 @@ private _sortListRightPanel = [ ]; //------------------------- Config handling -private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> QGVAR(sorts)); +private _class = ""; +private _displayName = ""; +private _statement = ""; +private _condition = ""; +private _finalArray = []; { - private _finalArray = []; - - private _class = configName _x; - private _displayName = getText (_x >> "displayName"); - private _statement = getText (_x >> "statement"); - private _condition = getText (_x >> "condition"); + _class = configName _x; + _displayName = getText (_x >> "displayName"); + _statement = getText (_x >> "statement"); + _condition = getText (_x >> "condition"); (getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"]; if (_statement != "") then { @@ -85,7 +94,7 @@ private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (confi if (_rightTabsList isNotEqualTo []) then { [_sortListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; }; -} forEach _configEntries; +} forEach ("(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> QGVAR(sorts))); -missionNamespace setVariable [QGVAR(sortListLeftPanel), _sortListLeftPanel]; -missionNamespace setVariable [QGVAR(sortListRightPanel), _sortListRightPanel]; +GVAR(sortListLeftPanel) = _sortListLeftPanel; +GVAR(sortListRightPanel) = _sortListRightPanel; diff --git a/addons/arsenal/functions/fnc_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf index 276ed6c0c9f..0d179427567 100644 --- a/addons/arsenal/functions/fnc_compileStats.sqf +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Alganthe + * Author: Alganthe, johnb43 * Create the internal stat arrays when needed for the first time. * * Arguments: @@ -15,89 +15,104 @@ if (!isNil QGVAR(statsListLeftPanel)) exitWith {}; private _fnc_addToTabs = { - params ["_tabsList", "_tabsToAddTo", "_sideString"]; + params ["_tabsList", "_tabsToAddTo", "_tabSide"]; - { - 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 "")]; + private _stat = []; - if (_availablePagesCount > 0) then { + // First gather all stats for a tab + { + // Make stat name + _stat = +_finalArray; + _stat set [0, [_class, _tabSide, [str _x, format ["0%1", _x]] select (_x < 10)] joinString ""]; - { - if (count _x < 5) exitWith { - (_currentTab select _forEachIndex) append [_arrayToSave]; - }; - } forEach _currentTab; - } else { - _currentTab pushBack [_arrayToSave]; - }; + (_tabsList select _x) pushBack _stat; } forEach _tabsToAddTo; }; +// Sort by priority private _fnc_sortLists = { params ["_tabsList"]; { - private _page = _x; + // Put priority up front { - { - reverse _x; - } forEach _x; + reverse _x; + } forEach _x; + + // Sort numerically + _x sort false; + + // Put it back at the rear + { + reverse _x; + } forEach _x; + } forEach _tabsList; +}; + +// Group stats into groups of 5 +private _fnc_toStatsArray = { + params ["_tabsList", "_tabsListAll"]; + + private _stats = []; + + { + _stats = []; - _x sort false; + for "_index" from 0 to count _x - 1 step 5 do { + _stats pushBack (_x select [_index, _index + 5]); + }; - { - reverse _x; - } forEach _x; - } forEach _page; + _tabsList set [_forEachIndex, _stats]; } forEach _tabsList; }; private _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 + [], // 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 = [ - [[]], // Optics 0 - [[]], // Side accs 1 - [[]], // Muzzle 2 - [[]], // Bipod 3 - [[]], // Mag 4 - [[]], // Throw 5 - [[]], // Put 6 - [[]] // Misc 7 + [], // 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 = ""; +private _stats = []; +private _displayName = ""; +private _showBar = false; +private _showText = false; +private _condition = ""; +private _priority = 0; { - 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"); + _class = configName _x; + _stats = getArray (_x >> "stats"); + _displayName = getText (_x >> "displayName"); + _showBar = getNumber (_x >> "showBar") == 1; + _showText = getNumber (_x >> "showText") == 1; + _condition = getText (_x >> "condition"); + _priority = getNumber (_x >> "priority"); (getArray (_x >> "tabs")) params ["_leftTabsList", "_rightTabsList"]; if (_condition != "") then { @@ -123,12 +138,16 @@ private _configEntries = "(getNumber (_x >> 'scope')) == 2" configClasses (confi if (_rightTabsList isNotEqualTo []) then { [_statsListRightPanel, _rightTabsList, "R"] call _fnc_addToTabs; }; -} forEach _configEntries; +} forEach ("(getNumber (_x >> 'scope')) == 2" configClasses (configFile >> "ace_arsenal_stats")); +// Sort [_statsListLeftPanel] call _fnc_sortLists; [_statsListRightPanel] call _fnc_sortLists; -//------------------------- Config Handling +// Group into 5 stats +[_statsListLeftPanel] call _fnc_toStatsArray; +[_statsListRightPanel] call _fnc_toStatsArray; -missionNamespace setVariable [QGVAR(statsListLeftPanel), _statsListLeftPanel]; -missionNamespace setVariable [QGVAR(statsListRightPanel), _statsListRightPanel]; +//------------------------- Config Handling +GVAR(statsListLeftPanel) = _statsListLeftPanel; +GVAR(statsListRightPanel) = _statsListRightPanel; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index 69b42c04fd3..58d3d97b9bb 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -55,7 +55,7 @@ private _selectedItem = switch (true) do { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((GVAR(virtualItems) select IDX_VIRT_WEAPONS) select _index); + } forEach ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _index); GVAR(currentItems) select _index }; @@ -73,7 +73,7 @@ private _selectedItem = switch (true) do { case IDC_buttonUniform: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_UNIFORM); + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIFORM); GVAR(currentItems) select IDX_CURR_UNIFORM }; @@ -81,7 +81,7 @@ private _selectedItem = switch (true) do { case IDC_buttonVest: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_VEST); + } forEach (GVAR(virtualItems) get IDX_VIRT_VEST); GVAR(currentItems) select IDX_CURR_VEST }; @@ -89,7 +89,7 @@ private _selectedItem = switch (true) do { case IDC_buttonBackpack: { { ["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_BACKPACK); + } forEach (GVAR(virtualItems) get IDX_VIRT_BACKPACK); GVAR(currentItems) select IDX_CURR_BACKPACK }; @@ -115,7 +115,7 @@ private _selectedItem = switch (true) do { case IDC_buttonHeadgear: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_HEADGEAR); + } forEach (GVAR(virtualItems) get IDX_VIRT_HEADGEAR); GVAR(currentItems) select IDX_CURR_HEADGEAR }; @@ -123,7 +123,7 @@ private _selectedItem = switch (true) do { case IDC_buttonGoggles: { { ["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_GOGGLES); + } forEach (GVAR(virtualItems) get IDX_VIRT_GOGGLES); GVAR(currentItems) select IDX_CURR_GOGGLES }; @@ -131,7 +131,7 @@ private _selectedItem = switch (true) do { case IDC_buttonNVG: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_NVG); + } forEach (GVAR(virtualItems) get IDX_VIRT_NVG); GVAR(currentItems) select IDX_CURR_NVG }; @@ -139,7 +139,7 @@ private _selectedItem = switch (true) do { case IDC_buttonBinoculars: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_BINO); + } forEach (GVAR(virtualItems) get IDX_VIRT_BINO); GVAR(currentItems) select IDX_CURR_BINO }; @@ -147,7 +147,7 @@ private _selectedItem = switch (true) do { case IDC_buttonMap: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_MAP); + } forEach (GVAR(virtualItems) get IDX_VIRT_MAP); GVAR(currentItems) select IDX_CURR_MAP }; @@ -155,7 +155,7 @@ private _selectedItem = switch (true) do { case IDC_buttonCompass: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_COMPASS); + } forEach (GVAR(virtualItems) get IDX_VIRT_COMPASS); GVAR(currentItems) select IDX_CURR_COMPASS }; @@ -163,7 +163,7 @@ private _selectedItem = switch (true) do { case IDC_buttonRadio: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_RADIO); + } forEach (GVAR(virtualItems) get IDX_VIRT_RADIO); GVAR(currentItems) select IDX_CURR_RADIO }; @@ -171,7 +171,7 @@ private _selectedItem = switch (true) do { case IDC_buttonWatch: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_WATCH); + } forEach (GVAR(virtualItems) get IDX_VIRT_WATCH); GVAR(currentItems) select IDX_CURR_WATCH }; @@ -179,7 +179,7 @@ private _selectedItem = switch (true) do { case IDC_buttonGPS: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) select IDX_VIRT_COMMS); + } forEach (GVAR(virtualItems) get IDX_VIRT_COMMS); GVAR(currentItems) select IDX_CURR_COMMS }; @@ -194,7 +194,7 @@ private _selectedItem = switch (true) do { _ctrlPanel lbSetData [_lbAdd, _x]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]]; _ctrlPanel lbSetPictureRight [_lbAdd, _modPicture]; - } forEach (uiNamespace getVariable [QGVAR(faceCache), createHashMap]); + } forEach (uiNamespace getVariable QGVAR(faceCache)); GVAR(currentFace) }; @@ -202,7 +202,7 @@ private _selectedItem = switch (true) do { case IDC_buttonVoice: { { ["CfgVoice", configName _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); - } forEach (uiNamespace getVariable [QGVAR(voiceCache), []]); + } forEach (uiNamespace getVariable QGVAR(voiceCache)); GVAR(currentVoice) }; @@ -211,7 +211,7 @@ private _selectedItem = switch (true) do { // Insignia from config { ["CfgUnitInsignia", configName _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); - } forEach (uiNamespace getVariable [QGVAR(insigniaCache), []]); + } forEach (uiNamespace getVariable QGVAR(insigniaCache)); private _displayName = ""; private _className = ""; @@ -226,7 +226,7 @@ private _selectedItem = switch (true) do { _ctrlPanel lbSetData [_lbAdd, _className]; _ctrlPanel lbSetPicture [_lbAdd, getText (_x >> "texture")]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; - } forEach ("true" configClasses (missionConfigFile >> "CfgUnitInsignia")); + } forEach ("(if (isNumber (_x >> 'scope')) then {getNumber (_x >> 'scope')} else {2}) == 2" configClasses (missionConfigFile >> "CfgUnitInsignia")); GVAR(currentInsignia) }; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index 1740e08826c..eeaef11e771 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -41,8 +41,8 @@ if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgWeapons = configFile >> "CfgWeapons"; -private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; -private _rightPanelCache = uiNamespace getVariable [QGVAR(rightPanelCache), createHashMap]; +private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); +private _rightPanelCache = uiNamespace getVariable QGVAR(rightPanelCache); private _fnc_fill_right_Container = { params ["_configCategory", "_className", "_hasItemInfo", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; @@ -208,15 +208,15 @@ switch (_ctrlIDC) do { if (_leftPanelState) then { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _index)) arrayIntersect _compatibleItems); + } forEach ((keys ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)) arrayIntersect _compatibleItems); } else { { ["CfgWeapons", _x, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _index); + } forEach ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index); { ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select _index); + } forEach ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get _index); }; }; // Current primary & secondary muzzle compatible magazines @@ -225,48 +225,48 @@ switch (_ctrlIDC) do { if (_leftPanelState) then { { ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _compatibleMagsMuzzle); + } forEach ((keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) arrayIntersect _compatibleMagsMuzzle); }; }; // All compatible magazines case IDC_buttonMag: { { ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); + } forEach ((keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) arrayIntersect _allCompatibleMags); { ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) arrayIntersect _allCompatibleMags); + } forEach ((keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)) arrayIntersect _allCompatibleMags); }; // All magazines case IDC_buttonMagALL: { { ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + } forEach (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL); { ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL); + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL); }; // Grenades case IDC_buttonThrow: { { ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) select IDX_VIRT_GRENADES); + } forEach (GVAR(virtualItems) get IDX_VIRT_GRENADES); { ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GRENADES); + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES); }; // Explosives case IDC_buttonPut: { { ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES); + } forEach (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES); { ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) select IDX_VIRT_UNIQUE_EXPLOSIVES); + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES); }; // Misc. items case IDC_buttonMisc: { @@ -283,24 +283,34 @@ switch (_ctrlIDC) do { // "Regular" misc. items { - ["CfgWeapons", _x, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS) select {!(_x in _items)}); + if !(_x in _items) then { + ["CfgWeapons", _x, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS); // Unique items { - ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) select {!(_x in _items)}); + if !(_x in _items) then { + ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS); // Unique backpacks { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) select {!(_x in _items)}); + if !(_x in _items) then { + ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS); // Unique goggles { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) select {!(_x in _items)}); + if !(_x in _items) then { + ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES); // Unknown items { - ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) select {!(_x in _items)}); + if !(_x in _items) then { + ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS); }; // Custom buttons default { @@ -309,24 +319,34 @@ switch (_ctrlIDC) do { if (_items isNotEqualTo []) then { // "Regular" misc. items { - ["CfgWeapons", _x, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS) select {_x in _items}); + if (_x in _items) then { + ["CfgWeapons", _x, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS); // Unique items { - ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) select {_x in _items}); + if (_x in _items) then { + ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS); // Unique backpacks { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) select {_x in _items}); + if (_x in _items) then { + ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS); // Unique goggles { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) select {_x in _items}); + if (_x in _items) then { + ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES); // Unknown items { - ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) select {_x in _items}); + if (_x in _items) then { + ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; + }; + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS); }; }; }; diff --git a/addons/arsenal/functions/fnc_handleStats.sqf b/addons/arsenal/functions/fnc_handleStats.sqf index b1e38572ea0..95c078552d3 100644 --- a/addons/arsenal/functions/fnc_handleStats.sqf +++ b/addons/arsenal/functions/fnc_handleStats.sqf @@ -52,27 +52,35 @@ if (!isNil "_itemCfg") then { // Get the proper list and page if (_leftPanel) then { - [true, (GVAR(statsListLeftPanel)) select _statsIndex, GVAR(statsPagesLeft) select _statsIndex] + [(GVAR(statsListLeftPanel)) select _statsIndex, GVAR(statsPagesLeft) select _statsIndex] } else { - [false, (GVAR(statsListRightPanel)) select _statsIndex, GVAR(statsPagesRight) select _statsIndex] - } params ["_isLeftPanel", "_statsArray", "_currentPage"]; + [(GVAR(statsListRightPanel)) select _statsIndex, GVAR(statsPagesRight) select _statsIndex] + } params ["_statsArray", "_currentPage"]; private _statsList = _statsArray select _currentPage; private _statsCount = 0; // Handle titles, bars and text _statsList = _statsList select [0, 5]; + if (_statsList isNotEqualTo []) then { + private _statsTitleCtrl = controlNull; + private _statsTitleIDC = -1; + private _statsBackgroundCtrl = controlNull; + private _statsBarCtrl = controlNull; + private _statsTextCtrl = controlNull; + private _textStatementResult = ""; + { _x params ["_ID", "_configEntry", "_title", "_bools", "_statements"]; _bools params ["_showBar", "_showText"]; _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; - private _statsTitleCtrl = _display displayCtrl (IDC_statsTitle1 + _forEachIndex * 4); - private _statsTitleIDC = ctrlIDC _statsTitleCtrl; - private _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); - private _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); - private _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); + _statsTitleCtrl = _display displayCtrl (IDC_statsTitle1 + _forEachIndex * 4); + _statsTitleIDC = ctrlIDC _statsTitleCtrl; + _statsBackgroundCtrl = _display displayCtrl (_statsTitleIDC + 1); + _statsBarCtrl = _display displayCtrl (_statsTitleIDC + 2); + _statsTextCtrl = _display displayCtrl (_statsTitleIDC + 3); _statsCount = _statsCount + 1; _statsTitleCtrl ctrlSetText _title; @@ -81,7 +89,6 @@ if (!isNil "_itemCfg") then { // Handle bars if (_showBar) then { _statsBarCtrl progressSetPosition ([_configEntry, _itemCfg] call _barStatement); - _statsBackgroundCtrl ctrlSetFade 0; _statsBarCtrl ctrlSetFade 0; } else { @@ -91,15 +98,14 @@ if (!isNil "_itemCfg") then { // Handle text entries if (_showText) then { - private _textStatementResult = [_configEntry, _itemCfg] call _textStatement; + _textStatementResult = [_configEntry, _itemCfg] call _textStatement; - if (_textStatementResult isEqualtype "") then { - _statsTextCtrl ctrlSetText _textStatementResult; - } else { - _statsTextCtrl ctrlSetText (str _textStatementResult); + if !(_textStatementResult isEqualtype "") then { + _textStatementResult = str _textStatementResult; }; - _statsTextCtrl ctrlSetTextColor ([[1,1,1,1], [0,0,0,1]] select (_showBar)); + _statsTextCtrl ctrlSetText _textStatementResult; + _statsTextCtrl ctrlSetTextColor ([[1, 1, 1, 1], [0, 0, 0, 1]] select (_showBar)); _statsTextCtrl ctrlSetFade 0; } else { _statsTextCtrl ctrlSetFade 1; @@ -114,8 +120,8 @@ if (!isNil "_itemCfg") then { _statsTextCtrl ]; } forEach (_statsList select { - _x params ["_ID","_configEntry", "_title", "_bools", "_statements"]; - _statements params [["_barStatement", {}, [{}]], ["_textStatement", {}, [{}]], ["_condition", {true}, [{}]]]; + _x params ["", "_configEntry", "", "", "_statements"]; + _statements params ["", "", ["_condition", {true}, [{}]]]; ([_configEntry, _itemCfg] call _condition) }); @@ -131,12 +137,12 @@ if (!isNil "_itemCfg") then { ]; _statsBoxCtrl ctrlCommit 0; - GVAR(statsInfo) = [_isLeftPanel, _statsIndex, _control, _curSel, _itemCfg]; + GVAR(statsInfo) = [_leftPanel, _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 " "); + _statsPreviousPageCtrl ctrlEnable (_currentPage > 0); + _statsNextPageCtrl ctrlEnable (_currentPage + 1 < count _statsArray); + _statsCurrentPageCtrl ctrlSetText ([LLSTRING(page), str (_currentPage + 1)] joinString " "); { _x ctrlSetFade 0; @@ -148,9 +154,10 @@ if (!isNil "_itemCfg") then { ]; }; + // Check if in left or right panel if (ctrlIDC _control == IDC_leftTabContent) then { + // Faces, voices and insigna do not have stats if ([IDC_buttonFace, IDC_buttonVoice, IDC_buttonInsignia] find GVAR(currentLeftPanel) > -1) then { - [[1, 2, 3, 4, 5]] call _hideUnusedFnc; _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, @@ -224,6 +231,7 @@ if (!isNil "_itemCfg") then { }; }; } else { + // If nothing is chosen, hide stats [[1, 2, 3, 4, 5]] call _hideUnusedFnc; _statsBoxCtrl ctrlSetPosition [ (0.5 - WIDTH_TOTAL / 2) + WIDTH_GAP, diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 4b86591bfba..38db27e1965 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -113,6 +113,7 @@ GVAR(ignoreFirstSortPanelCall) = nil; GVAR(selectedWeaponType) = nil; GVAR(virtualItems) = nil; GVAR(virtualItemsFlat) = nil; +GVAR(virtualItemsFlatAll) = nil; GVAR(currentItems) = nil; GVAR(currentFace) = nil; GVAR(currentVoice) = nil; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index ccc216feb6f..c4c90c2b268 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -43,7 +43,37 @@ if (isNil QGVAR(defaultLoadoutsList)) then { }; if (isNil QGVAR(virtualItems)) then { - GVAR(virtualItems) = EMPTY_VIRTUAL_ARSENAL; + private _virtualItems = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; + + _virtualItems = createHashMapFromArray _virtualItems; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItems set [_index, createHashMap]; + }; + + GVAR(virtualItems) = _virtualItems; + + // Flatten out hashmaps for easy checking later + private _virtualItemsFlat = +_virtualItems; + private _weapons = _virtualItemsFlat deleteAt IDX_VIRT_WEAPONS; + private _attachments = _virtualItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItemsFlat merge [_virtualItemsFlat deleteAt _index, true]; + }; + + for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _virtualItemsFlat merge [_weapons deleteAt _index, true]; + }; + + for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _virtualItemsFlat merge [_attachments deleteAt _index, true]; + }; + + GVAR(virtualItemsFlat) = _virtualItemsFlat; }; GVAR(currentFace) = face GVAR(center); @@ -74,61 +104,48 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; // If bino, add it in a different place than regular weapons if (_forEachIndex != IDX_LOADOUT_BINO) then { - ((GVAR(virtualItems) select IDX_VIRT_WEAPONS) select _forEachIndex) pushBackUnique _weapon; + ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _forEachIndex) set [_weapon, nil]; } else { - (GVAR(virtualItems) select IDX_VIRT_BINO) pushBackUnique _weapon; + (GVAR(virtualItems) get IDX_VIRT_BINO) set [_weapon, nil]; }; }; // Add weapon attachments { if (_x != "") then { - ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select _forEachIndex) pushBackUnique (_x call FUNC(baseWeapon)); + ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _forEachIndex) set [_x call FUNC(baseWeapon), nil]; }; } forEach [_optics, _flashlight, _muzzle, _bipod]; // Add magazines { - // Check if there is a magazine and if it has some ammo - if ((_x param [0, ""]) != "" && {(_x select 1) > 0}) then { - (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) pushBackUnique (_x select 0); + // Check if there is a magazine (ammo count is unnecssary to check) + if ((_x param [0, ""]) != "") then { + (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL) set [_x select 0, nil]; }; } forEach [_primaryMagazine, _secondaryMagazine]; }; - // Uniform - case IDX_LOADOUT_UNIFORM: { - _x params [["_containerClass", ""]]; - if (_containerClass != "") then { - (GVAR(virtualItems) select IDX_VIRT_UNIFORM) pushBackUnique _containerClass; - }; - }; - // Vest - case IDX_LOADOUT_VEST: { - _x params [["_containerClass", ""]]; - - if (_containerClass != "") then { - (GVAR(virtualItems) select IDX_VIRT_VEST) pushBackUnique _containerClass; - }; - }; - // Backpack + // Uniform, vest, backpack + case IDX_LOADOUT_UNIFORM; + case IDX_LOADOUT_VEST; case IDX_LOADOUT_BACKPACK: { _x params [["_containerClass", ""]]; if (_containerClass != "") then { - (GVAR(virtualItems) select IDX_VIRT_BACKPACK) pushBackUnique _containerClass; + (GVAR(virtualItems) get (_forEachIndex + 1)) set [_containerClass, nil]; }; }; // Helmet case IDX_LOADOUT_HEADGEAR: { if (_x != "") then { - (GVAR(virtualItems) select IDX_VIRT_HEADGEAR) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_HEADGEAR) set [_x, nil]; }; }; // Facewear case IDX_LOADOUT_GOGGLES: { if (_x != "") then { - (GVAR(virtualItems) select IDX_VIRT_GOGGLES) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_GOGGLES) set [_x, nil]; }; }; // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs @@ -136,13 +153,32 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; { // Order of storing virtualItems is different than what getUnitLoadout returns, so do some math if (_x != "") then { - (GVAR(virtualItems) select (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex))) pushBackUnique _x; + (GVAR(virtualItems) get (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex))) set [_x, nil]; }; } forEach _x; }; }; } forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout +// Get a list of all virtual items, including single panel items that are unique +private _virtualItemsFlat = +GVAR(virtualItems); +private _weapons = _virtualItemsFlat deleteAt IDX_VIRT_WEAPONS; +private _attachments = _virtualItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; + +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItemsFlat merge [_virtualItemsFlat deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _virtualItemsFlat merge [_weapons deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _virtualItemsFlat merge [_attachments deleteAt _index, true]; +}; + +GVAR(virtualItemsFlatAll) = _virtualItemsFlat; + // Update current item list call FUNC(updateCurrentItemsList); diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index ef85be138f4..6347be48ef5 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -67,7 +67,7 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); // Remove all magazines from the previous weapon that aren't compatible with the new one call _fnc_clearPreviousWepMags; @@ -79,10 +79,8 @@ switch (GVAR(currentLeftPanel)) do { // Remove linked items if unavailable if (_linkedItems isNotEqualTo []) then { - private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); - { - if !(_x in _availableAttachments) then { + if !(_x in GVAR(virtualItemsFlat)) then { GVAR(center) removePrimaryWeaponItem _x; }; } forEach _linkedItems; @@ -135,7 +133,7 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); // Remove all magazines from the previous weapon that aren't compatible with the new one call _fnc_clearPreviousWepMags; @@ -147,10 +145,8 @@ switch (GVAR(currentLeftPanel)) do { // Remove linked items if unavailable if (_linkedItems isNotEqualTo []) then { - private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); - { - if !(_x in _availableAttachments) then { + if !(_x in GVAR(virtualItemsFlat)) then { GVAR(center) removeHandgunItem _x; }; } forEach _linkedItems; @@ -189,6 +185,7 @@ switch (GVAR(currentLeftPanel)) do { // Secondary weapon case IDC_buttonSecondaryWeapon: { private _currentWeapon = GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON; + private _isDisposable = _item in (uiNamespace getVariable QGVAR(CBAdisposableLaunchers)); // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { @@ -204,7 +201,7 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); // Remove all magazines from the previous weapon that aren't compatible with the new one call _fnc_clearPreviousWepMags; @@ -216,10 +213,8 @@ switch (GVAR(currentLeftPanel)) do { // Remove linked items if unavailable if (_linkedItems isNotEqualTo []) then { - private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); - { - if !(_x in _availableAttachments) then { + if !(_x in GVAR(virtualItemsFlat)) then { GVAR(center) removeSecondaryWeaponItem _x; }; } forEach _linkedItems; @@ -246,7 +241,7 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_WEAPON // If item is a disposable launcher, delay a bit to show new compatible items - if (_item in (uiNamespace getVariable [QGVAR(CBAdisposableLaunchers), []])) then { + if (_isDisposable) then { [{ _this call FUNC(fillRightPanel); }, [_display, _selectCorrectPanelWeapon]] call CBA_fnc_execNextFrame; @@ -255,11 +250,22 @@ switch (GVAR(currentLeftPanel)) do { }; }; - // Make unit switch to new item - call FUNC(showItem); + // If item is a disposable launcher, delay a bit to show new compatible items + if (_isDisposable) then { + [{ + // Make unit switch to new item + call FUNC(showItem); - // Display new items's info on the bottom right - [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + // Display new items's info on the bottom right + _this call FUNC(itemInfo); + }, [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item]] call CBA_fnc_execNextFrame; + } else { + // Make unit switch to new item + call FUNC(showItem); + + // Display new items's info on the bottom right + [_display, _control, _curSel, configFile >> "CfgWeapons" >> _item] call FUNC(itemInfo); + }; }; // Headgear case IDC_buttonHeadgear: { @@ -301,7 +307,7 @@ switch (GVAR(currentLeftPanel)) do { private _index = count _uniformItems - 1; // Remove any items that can't fit in the container (this prevents overloading) - while {loadUniform GVAR(center) > 1} do { + while {loadUniform GVAR(center) > 1 || {_index < 0}} do { GVAR(center) removeItemFromUniform (_uniformItems select _index); DEC(_index); }; @@ -342,7 +348,7 @@ switch (GVAR(currentLeftPanel)) do { private _index = count _vestItems - 1; // Remove any items that can't fit in the container (this prevents overloading) - while {loadVest GVAR(center) > 1} do { + while {loadVest GVAR(center) > 1 || {_index < 0}} do { GVAR(center) removeItemFromVest (_vestItems select _index); DEC(_index); }; @@ -380,7 +386,7 @@ switch (GVAR(currentLeftPanel)) do { private _index = count _backpackItems - 1; // Remove any items that can't fit in the container (this prevents overloading) - while {loadBackpack GVAR(center) > 1} do { + while {loadBackpack GVAR(center) > 1 || {_index < 0}} do { GVAR(center) removeItemFromBackpack (_backpackItems select _index); DEC(_index); }; @@ -457,7 +463,7 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new binocular private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL); + private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); // Remove all magazines from the previous binocular that aren't compatible with the new one call _fnc_clearPreviousWepMags; @@ -469,10 +475,8 @@ switch (GVAR(currentLeftPanel)) do { // Remove linked items if unavailable if (_linkedItems isNotEqualTo []) then { - private _availableAttachments = flatten (GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS); - { - if !(_x in _availableAttachments) then { + if !(_x in GVAR(virtualItemsFlat)) then { GVAR(center) removeBinocularItem _x; }; } forEach _linkedItems; diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index 1a0bf1b8ed3..bc96631d6d6 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -20,7 +20,7 @@ if (_curSel < 0) exitwith {}; private _display = ctrlParent _control; private _item = _control lbData _curSel; -private _currentItemsIndex = 18 + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun, IDC_buttonBinoculars] find GVAR(currentLeftPanel)); +private _currentItemsIndex = IDX_CURR_PRIMARY_WEAPON_ITEMS + ([IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun, IDC_buttonBinoculars] find GVAR(currentLeftPanel)); private _itemIndex = [IDC_buttonMuzzle, IDC_buttonItemAcc, IDC_buttonOptic, IDC_buttonBipod, IDC_buttonCurrentMag, IDC_buttonCurrentMag2] find GVAR(currentRightPanel); // Check which right panel has changed @@ -31,10 +31,8 @@ switch (_currentItemsIndex) do { if (_item == "") then { GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex); } else { - private _currentItem = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex; - // Don't add item if it isn't a different item than what the unit already has - if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + if (_item != ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex)) then { GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; }; }; @@ -47,26 +45,25 @@ switch (_currentItemsIndex) do { }; // Secondary weapon case IDX_CURR_SECONDARY_WEAPON_ITEMS: { - private _cbaDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; + private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; // If removal if (_item == "") then { - if (_cbaDisposable) exitWith { - TRACE_1("ignoring unload of disposable",secondaryWeapon GVAR(center)); + // Don't unload magazines from diposable weapons + if (_isDisposable && {_itemIndex > 3}) exitWith { + TRACE_1("Ignoring unload of magazine from disposable",secondaryWeapon GVAR(center)); }; GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex); } else { - private _currentItem = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; - // Don't add item if it isn't a different item than what the unit already has - if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + if (_item != ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex)) then { GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; }; }; // Update currentItems - if (!_cbaDisposable) then { + if !(_isDisposable && {_itemIndex > 3}) then { (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; }; @@ -78,10 +75,8 @@ switch (_currentItemsIndex) do { if (_item == "") then { GVAR(center) removeHandgunItem ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex); } else { - private _currentItem = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex; - // Don't add item if it isn't a different item than what the unit already has - if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + if (_item != ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex)) then { GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; }; }; @@ -97,10 +92,8 @@ switch (_currentItemsIndex) do { if (_item == "") then { GVAR(center) removeBinocularItem ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex); } else { - private _currentItem = (GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex; - // Don't add item if it isn't a different item than what the unit already has - if !(_item in [_currentItem, _currentItem call FUNC(baseWeapon)]) then { + if (_item != ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex)) then { GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; }; }; diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf index b4c6760101f..d9fbc9b38ad 100644 --- a/addons/arsenal/functions/fnc_openBox.sqf +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -50,12 +50,45 @@ GVAR(currentBox) = _object; if (_mode) then { // Add all the items from the game that the arsenal has detected - GVAR(virtualItems) = +(uiNamespace getVariable [QGVAR(configItems), []]); - GVAR(virtualItemsFlat) = +(uiNamespace getVariable [QGVAR(configItemsFlat), []]); + GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); + GVAR(virtualItemsFlat) = +(uiNamespace getVariable QGVAR(configItemsFlat)); } else { // Add only specified items to the arsenal - GVAR(virtualItems) = +(_object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]); - GVAR(virtualItemsFlat) = flatten GVAR(virtualItems); + private _virtualItems = _object getVariable QGVAR(virtualItems); + + GVAR(virtualItems) = if (isNil "_virtualItems") then { + _virtualItems = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; + + _virtualItems = createHashMapFromArray _virtualItems; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItems set [_index, createHashMap]; + }; + } else { + +_virtualItems + }; + + // Flatten out hashmaps for easy checking later + private _virtualItemsFlat = +_virtualItems; + private _weapons = _virtualItemsFlat deleteAt IDX_VIRT_WEAPONS; + private _attachments = _virtualItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _virtualItemsFlat merge [_virtualItemsFlat deleteAt _index, true]; + }; + + for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _virtualItemsFlat merge [_weapons deleteAt _index, true]; + }; + + for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _virtualItemsFlat merge [_attachments deleteAt _index, true]; + }; + + GVAR(virtualItemsFlat) = _virtualItemsFlat; }; GVAR(center) = _center; diff --git a/addons/arsenal/functions/fnc_removeSort.sqf b/addons/arsenal/functions/fnc_removeSort.sqf new file mode 100644 index 00000000000..8b9c818217e --- /dev/null +++ b/addons/arsenal/functions/fnc_removeSort.sqf @@ -0,0 +1,54 @@ +#include "script_component.hpp" +/* + * Author: johnb43 + * Remove a sort from ACE Arsenal. + * + * Arguments: + * 0: Array of IDs + * + * Return Value: + * None + * + * Example: + * + [["scopeSortL00", "scopeSortL01", "scopeSortL02", "scopeSortR07"]] call ace_arsenal_fnc_removeSort; + * + * Public: Yes +*/ + +params ["_IDList"]; + +// Compile sorts from config (in case this is called before preInit) +call FUNC(compileSorts); + +private _currentID = ""; +private _stringCount = 0; +private _tabSide = ""; +private _tab = ""; +private _tabToChange = []; + +{ + _currentID = _x; + _stringCount = count _currentID; + + // Make sure to keep at least 1 sort per category, so make default sort not deletable + if ("ace_alphabetically" in toLower (_currentID select [0, _stringCount - 3])) then { + continue; + }; + + // Get tab info + _tabSide = _currentID select [_stringCount - 3, 1]; + _tab = _currentID select [_stringCount - 2, 2]; + + _tab = parseNumber _tab; + + // Check which side to delete it from + _tabToChange = if (_tabSide == "R") then { + GVAR(sortListRightPanel) select _tab + } else { + GVAR(sortListLeftPanel) select _tab + }; + + // Remove entry (all names are unique, there are no duplicates) + _tabToChange deleteAt (_tabToChange findIf {_x select 0 == _currentID}); +} forEach _IDList; diff --git a/addons/arsenal/functions/fnc_removeStat.sqf b/addons/arsenal/functions/fnc_removeStat.sqf index 585459a9ddb..8c480c5a1b2 100644 --- a/addons/arsenal/functions/fnc_removeStat.sqf +++ b/addons/arsenal/functions/fnc_removeStat.sqf @@ -17,47 +17,68 @@ params ["_IDList"]; +// Compile stats from config (in case this is called before preInit) call FUNC(compileStats); +private _currentID = ""; +private _stringCount = 0; +private _tabSide = ""; +private _tab = ""; +private _tabToChange = []; +private _changes = []; + { - private _currentID = _x; - private _stringCount = count _currentID; - private _side = _currentID select [_stringCount - 3, 1]; - private _tab = _currentID select [_stringCount - 2, 2]; + // Get tab info + _currentID = _x; + _stringCount = count _currentID; + _tabSide = _currentID select [_stringCount - 3, 1]; + _tab = _currentID select [_stringCount - 2, 2]; _tab = parseNumber _tab; - private _tabToChange = if (_side == "R") then { + // Check which side to delete it from + _tabToChange = if (_tabSide == "R") then { GVAR(statsListRightPanel) select _tab } else { GVAR(statsListLeftPanel) select _tab }; + // Delete stat { _x deleteAt (_x findIf {_x select 0 == _currentID}); } forEach _tabToChange; + + // Store information, so that only tabs that were changed can be sorted again + _changes pushBackUnique [_tab, _tabSide]; } forEach _IDList; -// Clear empty pages -private _fnc_deleteEmptyPage = { - params ["_list"]; +private _statsFlat = []; +private _stats = []; - { - private _evaluatedTab = _forEachIndex; +// Fill empty spots +{ + _x params ["_tab", "_tabSide"]; + + _tabToChange = if (_tabSide == "R") then { + GVAR(statsListRightPanel) + } else { + GVAR(statsListLeftPanel) + }; - { - if (count _x == 0) then { - _markedForDeletion pushBack [_evaluatedTab, _forEachIndex]; - }; - } forEach _x; + _statsFlat = []; - { - (_list select (_x select 0)) deleteAt (_x select 1); - } forEach _markedForDeletion; - } forEach (_this select 0); -}; + // Get all stats of a tab into a single array + { + _statsFlat append _x; + } forEach (_tabToChange select _tab); -private _markedForDeletion = []; + // Priority has stayed intact, so no need to sort + _stats = []; + + // Group stats into groups of 5 + for "_index" from 0 to count _statsFlat - 1 step 5 do { + _stats pushBack (_statsFlat select [_index, _index + 5]); + }; -[GVAR(statsListLeftPanel)] call _fnc_deleteEmptyPage; -[GVAR(statsListRightPanel)] call _fnc_deleteEmptyPage; + _tabToChange set [_tab, _stats]; +} forEach _changes; diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf index 737419a05bd..e6a8d4c5707 100644 --- a/addons/arsenal/functions/fnc_removeVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -28,55 +28,70 @@ if (_items isEqualType true) then { [_object, _global] call FUNC(removeBox); }; } else { + private _cargo = _object getVariable QGVAR(virtualItems); + + if (isNil "_cargo") exitWith { + [_object, _global] call FUNC(removeBox); + }; + // Make sure all items are in string form, then convert to config case (non-existent items return "") _items = (_items select {_x isEqualType ""}) apply {_x call EFUNC(common,getConfigName)}; // Remove any invalid/non-existing items _items = _items - [""]; - private _cargo = _object getVariable [QGVAR(virtualItems), EMPTY_VIRTUAL_ARSENAL]; - private _isEmpty = true; - private _newItems = []; - // Remove items from lists { - switch (_forEachIndex) do { + switch (true) do { // Weapons - case IDX_VIRT_WEAPONS: { - _cargo set [_forEachIndex, [ - (_x select IDX_VIRT_PRIMARY_WEAPONS) - _items, - (_x select IDX_VIRT_SECONDARY_WEAPONS) - _items, - (_x select IDX_VIRT_HANDGUN_WEAPONS) - _items - ]]; - - // Check that there are still items left in the arsenal - _isEmpty = (_cargo select _forEachIndex) isEqualTo [[], [], []]; + case (_x in ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS)): { + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) deleteAt _x; }; - // Weapon attachments - case IDX_VIRT_ATTACHMENTS: { - _cargo set [_forEachIndex, [ - (_x select IDX_VIRT_OPTICS_ATTACHMENTS) - _items, - (_x select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) - _items, - (_x select IDX_VIRT_MUZZLE_ATTACHMENTS) - _items, - (_x select IDX_VIRT_BIPOD_ATTACHMENTS) - _items - ]]; - // Check that there are still items left in the arsenal - _isEmpty = _isEmpty && {(_cargo select _forEachIndex) isEqualTo [[], [], [], []]}; + // Weapon attachments + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) deleteAt _x; + }; + case (_x in ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)): { + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) deleteAt _x; }; - // Rest - default { - _newItems = _x - _items; - _cargo set [_forEachIndex, _newItems]; - // Check that there are still items left in the arsenal - _isEmpty = _isEmpty && {_newItems isEqualTo []}; - }; + // Other + default { + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + if (_x in (_cargo get _index)) exitWith { + (_cargo get _index) deleteAt _x; + }; + }; + }; }; - } forEach _cargo; + } forEach _items; + + private _empty = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] + ]; + + _empty = createHashMapFromArray _empty; + + for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _empty set [_index, createHashMap]; + }; // If nothing is left, remove arsenal from object - if (_isEmpty) then { + if (_cargo isEqualTo _empty) then { [_object, _global] call FUNC(removeBox); } else { _object setVariable [QGVAR(virtualItems), _cargo, _global]; diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf index b6c0921d10d..82b00208b3e 100644 --- a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -43,13 +43,18 @@ private _cfgVehicles = configFile >> "CfgVehicles"; // Check weapon & weapon attachments { - // Skip magazines + // Magazines if (_forEachIndex in [4, 5]) then { - continue; - }; + _uniqueBaseCfgText = (getText (_cfgMagazines >> _x >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); - if (_x != "") then { - _weaponsInfo set [_forEachIndex, _x call FUNC(baseWeapon)]; + if (_uniqueBaseCfgText != "") then { + _weaponsInfo set [_forEachIndex, _uniqueBaseCfgText]; + }; + } else { + // Other + if (_x != "") then { + _weaponsInfo set [_forEachIndex, _x call FUNC(baseWeapon)]; + }; }; } forEach _weaponsInfo; }; @@ -57,47 +62,68 @@ private _cfgVehicles = configFile >> "CfgVehicles"; case IDX_LOADOUT_UNIFORM; case IDX_LOADOUT_VEST; case IDX_LOADOUT_BACKPACK: { - _x params ["", ["_items", []]]; + _x params [["_containerClass", ""], ["_items", []]]; - // Check if container has items that need replacing with a defined base - { - switch (true) do { - // Containers have 2 entries: Name and isBackpack - case (_x isEqualTypeArray ["", false]); - // Misc. items have 2 entries: Name and amount - case (_x isEqualTypeArray ["", 0]): { - _x params ["_item", "_arg"]; - - if (_item != "") then { - _uniqueBaseCfgText = (getText ([_cfgWeapons, _cfgVehicles] select ((_arg isEqualType false) && {_arg}) >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); - - if (_uniqueBaseCfgText != "") then { - _x set [0, _uniqueBaseCfgText]; + if (_containerClass != "") then { + _uniqueBaseCfgText = (getText ([_cfgWeapons, _cfgVehicles] select (_forEachIndex == IDX_LOADOUT_BACKPACK) >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + (_x select 0) set [0, _uniqueBaseCfgText]; + }; + + // Check if container has items that need replacing with a defined base + { + switch (true) do { + // Containers have 2 entries: Name and isBackpack + case (_x isEqualTypeArray ["", false]); + // Misc. items have 2 entries: Name and amount + case (_x isEqualTypeArray ["", 0]): { + _x params ["_item", "_arg"]; + + if (_item != "") then { + _uniqueBaseCfgText = (getText ([_cfgWeapons, _cfgVehicles] select ((_arg isEqualType false) && {_arg}) >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; }; }; - }; - // Weapons have 2 entries: Weapon info array and amount - case (_x isEqualTypeArray [[], 0]): { - _weapon = (_x select 0) select 0; - - if (_weapon != "") then { - (_x select 0) set [0, _weapon call FUNC(baseWeapon)]; + // Weapons have 2 entries: Weapon info array and amount + case (_x isEqualTypeArray [[], 0]): { + _weaponsInfo = _x select 0; + + // Check weapon & weapon attachments + { + // Magazines + if (_forEachIndex in [4, 5]) then { + _uniqueBaseCfgText = (getText (_cfgMagazines >> _x >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _weaponsInfo set [_forEachIndex, _uniqueBaseCfgText]; + }; + } else { + // Other + if (_x != "") then { + _weaponsInfo set [_forEachIndex, _x call FUNC(baseWeapon)]; + }; + }; + } forEach _weaponsInfo; }; - }; - // Magazines have 3 entries: Name, amount and ammo count - case (_x isEqualTypeArray ["", 0, 0]): { - _x params ["_item"]; + // Magazines have 3 entries: Name, amount and ammo count + case (_x isEqualTypeArray ["", 0, 0]): { + _x params ["_item"]; - if (_item != "") then { - _uniqueBaseCfgText = (getText (_cfgMagazines >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + if (_item != "") then { + _uniqueBaseCfgText = (getText (_cfgMagazines >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); - if (_uniqueBaseCfgText != "") then { - _x set [0, _uniqueBaseCfgText]; + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; }; }; }; - }; - } forEach _items; + } forEach _items; + }; }; // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs case IDX_LOADOUT_ASSIGNEDITEMS: { diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 8d0caaba7cf..0374a37a6cd 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -13,7 +13,16 @@ * Public: No */ -private _configItems = EMPTY_VIRTUAL_ARSENAL; +private _configItems = [ + [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], + [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] +]; + +_configItems = createHashMapFromArray _configItems; + +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _configItems set [_index, createHashMap]; +}; // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 @@ -47,53 +56,53 @@ private _isMiscItem = false; {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]} ): { // Convert type to array index - ((_configItems select IDX_VIRT_ATTACHMENTS) select ([TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] find _itemInfoType)) pushBackUnique (_className call FUNC(baseWeapon)); + ((_configItems get IDX_VIRT_ATTACHMENTS) get ([TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] find _itemInfoType)) set [_className call FUNC(baseWeapon), nil]; }; // Headgear case (_itemInfoType == TYPE_HEADGEAR): { - (_configItems select IDX_VIRT_HEADGEAR) pushBackUnique _className; + (_configItems get IDX_VIRT_HEADGEAR) set [_className, nil]; }; // Uniform case (_itemInfoType == TYPE_UNIFORM): { - (_configItems select IDX_VIRT_UNIFORM) pushBackUnique _className; + (_configItems get IDX_VIRT_UNIFORM) set [_className, nil]; }; // Vest case (_itemInfoType == TYPE_VEST): { - (_configItems select IDX_VIRT_VEST) pushBackUnique _className; + (_configItems get IDX_VIRT_VEST) set [_className, nil]; }; - // NVgs + // NVGs case (_simulationType == "NVGoggles"): { - (_configItems select IDX_VIRT_NVG) pushBackUnique _className; + (_configItems get IDX_VIRT_NVG) set [_className, nil]; }; // Binos case ( _simulationType == "Binocular" || {_simulationType == "Weapon" && {getNumber (_x >> "type") == TYPE_BINOCULAR_AND_NVG}} ): { - (_configItems select IDX_VIRT_BINO) pushBackUnique _className; + (_configItems get IDX_VIRT_BINO) set [_className call FUNC(baseWeapon), nil]; }; // Map case (_simulationType == "ItemMap"): { - (_configItems select IDX_VIRT_MAP) pushBackUnique _className; + (_configItems get IDX_VIRT_MAP) set [_className, nil]; }; // Compass case (_simulationType == "ItemCompass"): { - (_configItems select IDX_VIRT_COMPASS) pushBackUnique _className; + (_configItems get IDX_VIRT_COMPASS) set [_className, nil]; }; // Radio case (_simulationType == "ItemRadio"): { - (_configItems select IDX_VIRT_RADIO) pushBackUnique _className; + (_configItems get IDX_VIRT_RADIO) set [_className, nil]; }; // Watch case (_simulationType == "ItemWatch"): { - (_configItems select IDX_VIRT_WATCH) pushBackUnique _className; + (_configItems get IDX_VIRT_WATCH) set [_className, nil]; }; // GPS and UAV terminals case ( _simulationType == "ItemGPS" || {_itemInfoType == TYPE_UAV_TERMINAL} ): { - (_configItems select IDX_VIRT_COMMS) pushBackUnique _className; + (_configItems get IDX_VIRT_COMMS) set [_className, nil]; }; // Weapon, at the bottom to avoid adding binos case ( @@ -102,13 +111,13 @@ private _isMiscItem = false; ): { switch (getNumber (_x >> "type")) do { case TYPE_WEAPON_PRIMARY: { - ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_PRIMARY_WEAPONS) pushBackUnique (_className call FUNC(baseWeapon)); + ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) set [_className call FUNC(baseWeapon), nil]; }; case TYPE_WEAPON_HANDGUN: { - ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_HANDGUN_WEAPONS) pushBackUnique (_className call FUNC(baseWeapon)); + ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) set [_className call FUNC(baseWeapon), nil]; }; case TYPE_WEAPON_SECONDARY: { - ((_configItems select IDX_VIRT_WEAPONS) select IDX_VIRT_SECONDARY_WEAPONS) pushBackUnique (_className call FUNC(baseWeapon)); + ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) set [_className call FUNC(baseWeapon), nil]; }; }; }; @@ -120,7 +129,7 @@ private _isMiscItem = false; {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || {getText (_x >> "simulation") == "ItemMineDetector"} ): { - (_configItems select IDX_VIRT_MISC_ITEMS) pushBackUnique _className; + (_configItems get IDX_VIRT_MISC_ITEMS) set [_className, nil]; }; }; } forEach configProperties [_cfgWeapons, _filterFunction, true]; @@ -147,7 +156,7 @@ _putList = _putList apply {_x call EFUNC(common,getConfigName)}; _grenadeList = _grenadeList - [""]; _putList = _putList - [""]; -private _magazineMiscItems = []; +private _magazineMiscItems = createHashMap; // Get all other grenades, explosives (and similar) and magazines { @@ -156,23 +165,23 @@ private _magazineMiscItems = []; switch (true) do { // "Misc. items" magazines (e.g. spare barrels, intel, photos) case (getNumber (_x >> "ACE_isUnique") == 1): { - (_configItems select IDX_VIRT_MISC_ITEMS) pushBackUnique _className; - _magazineMiscItems pushBackUnique _className; + (_configItems get IDX_VIRT_MISC_ITEMS) set [_className, nil]; + _magazineMiscItems set [_className, nil]; }; // Grenades case (_className in _grenadeList): { - (_configItems select IDX_VIRT_GRENADES) pushBackUnique _className; + (_configItems get IDX_VIRT_GRENADES) set [_className, nil]; }; // Explosives case (_className in _putList): { - (_configItems select IDX_VIRT_EXPLOSIVES) pushBackUnique _className; + (_configItems get IDX_VIRT_EXPLOSIVES) set [_className, nil]; }; // Primary, handgun & secondary weapon magazines, and magazines that are forced with "ace_arsenal_hide = -1" case ( getNumber (_x >> QGVAR(hide)) == -1 || {getNumber (_x >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL, TYPE_MAGAZINE_MISSILE]} ): { - (_configItems select IDX_VIRT_ITEMS_ALL) pushBackUnique _className; + (_configItems get IDX_VIRT_ITEMS_ALL) set [_className, nil]; }; }; } forEach configProperties [_cfgMagazines, _filterFunction, true]; @@ -180,13 +189,13 @@ private _magazineMiscItems = []; // Get all backpacks { if (getNumber (_x >> "isBackpack") == 1) then { - (_configItems select IDX_VIRT_BACKPACK) pushBackUnique (configName _x); + (_configItems get IDX_VIRT_BACKPACK) set [configName _x, nil]; }; } forEach configProperties [configFile >> "CfgVehicles", _filterFunction, true]; // Get all facewear { - (_configItems select IDX_VIRT_GOGGLES) pushBackUnique (configName _x); + (_configItems get IDX_VIRT_GOGGLES) set [configName _x, nil]; } forEach configProperties [configFile >> "CfgGlasses", _filterFunction, true]; // Get all faces @@ -200,8 +209,7 @@ private _faceCategory = ""; { if (getNumber (_x >> "disabled") == 0 && {getText (_x >> "head") != ""} && {configName _x != "Default"}) then { - _dlcName = _x call EFUNC(common,getAddon); - + _dlcName = _x call EFUNC(common,ggetAddon); _modPicture = ""; if (_dlcName != "") then { @@ -217,30 +225,44 @@ private _faceCategory = ""; private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [configfile >> "CfgVoice" >> "NoVoice"]; // Get all insignia -private _insigniaCache = "true" configClasses (configFile >> "CfgUnitInsignia"); +private _insigniaCache = "(if (isNumber (_x >> 'scope')) then {getNumber (_x >> 'scope')} else {2}) == 2" configClasses (configFile >> "CfgUnitInsignia"); // Get all disposable launchers private _launchersConfig = configProperties [configFile >> "CBA_DisposableLaunchers"]; -private _launchers = []; +private _launchers = createHashMap; +private _launcher = ""; // Get the loaded launchers (used launchers aren't necessary) { - _launchers pushBackUnique ((getArray _x) param [0, ""]); + // Convert to config case + _launcher = ((getArray _x) param [0, ""]) call EFUNC(common,getConfigName); + + if (_launcher != "") then { + _launchers set [_launcher, nil]; + }; } forEach _launchersConfig; -// Convert list to config case -_launchers = _launchers apply {_x call EFUNC(common,getConfigName)}; +private _configItemsFlat = +_configItems; +private _weapons = _configItemsFlat deleteAt IDX_VIRT_WEAPONS; +private _attachments = _configItemsFlat deleteAt IDX_VIRT_ATTACHMENTS; -// Remove invalid/non-existent entries -_launchers = _launchers - [""]; +for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { + _configItemsFlat merge [_configItemsFlat deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_PRIMARY_WEAPONS to IDX_VIRT_HANDGUN_WEAPONS do { + _configItemsFlat merge [_weapons deleteAt _index, true]; +}; + +for "_index" from IDX_VIRT_OPTICS_ATTACHMENTS to IDX_VIRT_BIPOD_ATTACHMENTS do { + _configItemsFlat merge [_attachments deleteAt _index, true]; +}; // This contains config case entries only uiNamespace setVariable [QGVAR(configItems), _configItems]; -uiNamespace setVariable [QGVAR(configItemsFlat), flatten _configItems]; +uiNamespace setVariable [QGVAR(configItemsFlat), _configItemsFlat]; uiNamespace setVariable [QGVAR(faceCache), _faceCache]; uiNamespace setVariable [QGVAR(voiceCache), _voiceCache]; uiNamespace setVariable [QGVAR(insigniaCache), _insigniaCache]; -uiNamespace setVariable [QGVAR(grenadeCache), _grenadeList]; -uiNamespace setVariable [QGVAR(putCache), _putList]; uiNamespace setVariable [QGVAR(CBAdisposableLaunchers), _launchers]; uiNamespace setVariable [QGVAR(magazineMiscItems), _magazineMiscItems]; diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index b37ae37f022..117ad792978 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -133,7 +133,8 @@ private _itemCfg = configNull; private _value = ""; private _name = ""; -private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; +private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); +private _sortCache = uiNamespace getVariable QGVAR(sortCache); private _faceCache = if (_cfgClass == _cfgFaces) then { uiNamespace getVariable [QGVAR(faceCache), createHashMap] @@ -198,17 +199,21 @@ _for do { }; // Value can be any type - _value = [_itemCfg, _item, _quantity] call _statement; + _value = _sortCache getOrDefaultCall [format ["%1_%2_%3", _sortName, _item, _quantity], { + private _value = [_itemCfg, _item, _quantity] call _statement; - // If number, convert to string (keep 2 decimal after comma; Needed for correct weight sorting) - if (_value isEqualType 0) then { - _value = [_value, 8, 2] call CBA_fnc_formatNumber; - }; + // If number, convert to string (keep 2 decimal after comma; Needed for correct weight sorting) + if (_value isEqualType 0) then { + _value = [_value, 8, 2] call CBA_fnc_formatNumber; + }; - // If empty string, add alphabetically small char at beginning to make it sort correctly - if (_value isEqualTo "") then { - _value = "_"; - }; + // If empty string, add alphabetically small char at beginning to make it sort correctly + if (_value isEqualTo "") then { + _value = "_"; + }; + + _value + }, true]; // Save the current row's item's name in a cache and set text to it's sorting value if (_right) then { diff --git a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf index f60b82ba27a..75899c304a5 100644 --- a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf @@ -77,7 +77,7 @@ private _indexCurrentItems = -1; // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs case IDX_LOADOUT_ASSIGNEDITEMS: { { - // Order of storing virtualItems is different than what getUnitLoadout returns, so do some math + // Order of storing currentItems is different than what getUnitLoadout returns, so do some math GVAR(currentItems) set [IDX_CURR_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex), _x]; } forEach _x; }; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 446ab339ee3..8f45980fa8b 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -14,18 +14,18 @@ * Public: No */ -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_MISC_ITEMS, []]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL, []]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GRENADES, []]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_EXPLOSIVES, []]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_ATTACHMENTS, [[], [], [], []]]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_BACKPACKS, []]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GOGGLES, []]; -GVAR(virtualItems) set [IDX_VIRT_UNIQUE_UNKNOWN_ITEMS, []]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_MISC_ITEMS, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GRENADES, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_EXPLOSIVES, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_BACKPACKS, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GOGGLES, createHashMap]; +GVAR(virtualItems) set [IDX_VIRT_UNIQUE_UNKNOWN_ITEMS, createHashMap]; -private _configItems = uiNamespace getVariable [QGVAR(configItems), []]; -private _configItemsFlat = uiNamespace getVariable [QGVAR(configItemsFlat), []]; -private _magazineMiscItems = uiNamespace getVariable [QGVAR(magazineMiscItems), []]; +private _configItems = uiNamespace getVariable QGVAR(configItems); +private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); +private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; @@ -43,92 +43,92 @@ private _isWeapon = false; // Primary, Handgun, Secondary weapon magazines case ( _isMagazine && - {!(_x in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL))} && - {_x in (_configItems select IDX_VIRT_ITEMS_ALL)} + {!(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL))} && + {_x in (_configItems get IDX_VIRT_ITEMS_ALL)} ): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) set [_x, nil]; }; // Grenades case ( _isMagazine && - {!(_x in (GVAR(virtualItems) select IDX_VIRT_GRENADES))} && - {_x in (_configItems select IDX_VIRT_GRENADES)} + {!(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES))} && + {_x in (_configItems get IDX_VIRT_GRENADES)} ): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GRENADES) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES) set [_x, nil]; }; // Explosives case ( _isMagazine && - {!(_x in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES))} && - {_x in (_configItems select IDX_VIRT_EXPLOSIVES)} + {!(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES))} && + {_x in (_configItems get IDX_VIRT_EXPLOSIVES)} ): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_EXPLOSIVES) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES) set [_x, nil]; }; // Optics case ( _isWeapon && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS))} && - {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS)} + {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS))} && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)} ): { - ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS) pushBackUnique _x; + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x, nil]; }; // Flashlights case ( _isWeapon && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && - {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} + {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} ): { - ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS) pushBackUnique _x; + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x, nil]; }; // Muzzle attachments case ( _isWeapon && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS))} && - {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS)} + {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS))} && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)} ): { - ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS) pushBackUnique _x; + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x, nil]; }; // Bipods case ( _isWeapon && - {!(_x in ((GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS))} && - {_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS)} + {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS))} && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)} ): { - ((GVAR(virtualItems) select IDX_VIRT_UNIQUE_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS) pushBackUnique _x; + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x, nil]; }; // Misc. items case ( _isWeapon && - {!(_x in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS))} && - {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_OPTICS_ATTACHMENTS))} && - {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && - {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_MUZZLE_ATTACHMENTS))} && - {!(_x in ((_configItems select IDX_VIRT_ATTACHMENTS) select IDX_VIRT_BIPOD_ATTACHMENTS))} + {!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS))} && + {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS))} && + {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && + {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS))} && + {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS))} ): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; }; // "Misc. items" magazines (e.g. spare barrels, intel, photos) case ( _isMagazine && {_x in _magazineMiscItems} && - {!(_x in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS))} && - {_x in (_configItems select IDX_VIRT_MISC_ITEMS)} + {!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS))} && + {_x in (_configItems get IDX_VIRT_MISC_ITEMS)} ): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_MISC_ITEMS) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; }; // Backpacks case (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_BACKPACKS) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS) set [_x, nil]; }; // Facewear case (isClass (_cfgGlasses >> _x)): { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_GOGGLES) pushBackUnique _x; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES) set [_x, nil]; }; // Unknown default { // Don't add items that are part of the arsenal - if !(_x in _configItemsFlat) then { - (GVAR(virtualItems) select IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) pushBackUnique _x; + if !(_x in GVAR(virtualItemsFlatAll)) then { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil]; }; }; }; diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index 4bb6ce4deaa..2af87635de0 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -28,8 +28,8 @@ private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgVehicles = configFile >> "CfgVehicles"; private _cfgGlasses = configFile >> "CfgGlasses"; -private _weaponsArray = GVAR(virtualItems) select IDX_VIRT_WEAPONS; -private _accsArray = GVAR(virtualItems) select IDX_VIRT_ATTACHMENTS; +private _weapons = GVAR(virtualItems) get IDX_VIRT_WEAPONS; +private _attachments = GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS; private _name = ""; private _nullItemsAmount = 0; @@ -91,21 +91,21 @@ private _fnc_weaponCheck = { if (_index != -1) then { // If binos, choose differently if (_index == IDX_LOADOUT_BINO) then { - _x in (GVAR(virtualItems) select IDX_VIRT_BINO) + _x in (GVAR(virtualItems) get IDX_VIRT_BINO) } else { - _x in (_weaponsArray select _index) + _x in (_weapons get _index) }; } else { - _x in (_weaponsArray select IDX_VIRT_PRIMARY_WEAPONS) || - {_x in (_weaponsArray select IDX_VIRT_SECONDARY_WEAPONS)} || - {_x in (_weaponsArray select IDX_VIRT_HANDGUN_WEAPONS)} || - {_x in (GVAR(virtualItems) select IDX_VIRT_BINO)} + _x in (_weapons get IDX_VIRT_PRIMARY_WEAPONS) || + {_x in (_weapons get IDX_VIRT_SECONDARY_WEAPONS)} || + {_x in (_weapons get IDX_VIRT_HANDGUN_WEAPONS)} || + {_x in (GVAR(virtualItems) get IDX_VIRT_BINO)} }; } else { - _x in (_accsArray select IDX_VIRT_OPTICS_ATTACHMENTS) || - {_x in (_accsArray select IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || - {_x in (_accsArray select IDX_VIRT_MUZZLE_ATTACHMENTS)} || - {_x in (_accsArray select IDX_VIRT_BIPOD_ATTACHMENTS)} + _x in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS) || + {_x in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || + {_x in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS)} || + {_x in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS)} } ) then { _unavailableItemsList pushBackUnique _x; @@ -126,7 +126,7 @@ private _fnc_weaponCheck = { // Check if item exists if (isClass (_cfgMagazines >> _magazine)) then { // Check if item is available in arsenal - if !(_magazine in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL)) then { + if !(_magazine in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { _unavailableItemsList pushBackUnique _magazine; _weaponArray set [_forEachIndex, []]; INC(_unavailableItemsAmount); @@ -163,7 +163,7 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do // Check if item exists if (isClass (_cfgVehicles >> _item) || {isClass (_cfgWeapons >> _item)}) then { // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) select (_dataIndex + 1))) then { + if !(_item in (GVAR(virtualItems) get (_dataIndex + 1))) then { _unavailableItemsList pushBackUnique _item; _loadout set [_dataIndex, []]; INC(_unavailableItemsAmount); @@ -178,10 +178,10 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do if (isClass (_cfgMagazines >> _item)) then { // Check if item is available in arsenal if !( - _item in (GVAR(virtualItems) select IDX_VIRT_ITEMS_ALL) || - {_item in (GVAR(virtualItems) select IDX_VIRT_GRENADES)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_EXPLOSIVES)} || - {_item in (GVAR(virtualItems) select IDX_VIRT_MISC_ITEMS)} + _item in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL) || + {_item in (GVAR(virtualItems) get IDX_VIRT_GRENADES)} || + {_item in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)} || + {_item in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)} ) then { _unavailableItemsList pushBackUnique _item; ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; @@ -239,7 +239,7 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do // Check if item exists if (isClass (_cfgWeapons >> _item)) then { // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) select IDX_VIRT_HEADGEAR)) then { + if !(_item in (GVAR(virtualItems) get IDX_VIRT_HEADGEAR)) then { _unavailableItemsList pushBackUnique _item; _loadout set [_dataIndex, ""]; INC(_unavailableItemsAmount); @@ -259,7 +259,7 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do // Check if item exists if (isClass (_cfgGlasses >> _item)) then { // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) select IDX_VIRT_GOGGLES)) then { + if !(_item in (GVAR(virtualItems) get IDX_VIRT_GOGGLES)) then { _unavailableItemsList pushBackUnique _item; _loadout set [_dataIndex, ""]; INC(_unavailableItemsAmount); @@ -282,7 +282,7 @@ for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do // Check if item exists if (isClass (_cfgWeapons >> _item)) then { // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) select (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _subIndex)))) then { + if !(_item in (GVAR(virtualItems) get (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _subIndex)))) then { _unavailableItemsList pushBackUnique _item; _assignedItems set [_subIndex, ""]; INC(_unavailableItemsAmount); diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index fc130f1b8bb..431869cb14e 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -3,18 +3,18 @@ class GVAR(display) { idd = IDD_ace_arsenal; - enableSimulation=1; + enableSimulation = 1; onLoad = QUOTE([ARR_3('onLoad', _this, QQGVAR(display))] call FUNC(onArsenalOpen)); onUnload = QUOTE([ARR_3('onUnload', _this, QQGVAR(display))] call FUNC(onArsenalClose)); onKeyDown = QUOTE([ARR_3('onKeyDown', _this, QQGVAR(display))] call FUNC(onKeyDown)); onKeyUp = QUOTE(GVAR(shiftState) = _this select 2); onMouseButtonDown = QUOTE([ARR_3('onMouseButtonDown', _this, QQGVAR(display))] call FUNC(onMouseButtonDown)); onMouseButtonUp = QUOTE([ARR_3('onMouseButtonUp', _this, QQGVAR(display))] call FUNC(onMouseButtonUp)); - icon="\A3\Ui_f\data\Logos\a_64_ca.paa"; - logo="\A3\Ui_f\data\Logos\arsenal_1024_ca.paa"; + icon = "\A3\Ui_f\data\Logos\a_64_ca.paa"; + logo = "\A3\Ui_f\data\Logos\arsenal_1024_ca.paa"; class ControlsBackground { class blackLeft: ctrlStatic { - colorBackground[]={0,0,0,1}; + colorBackground[] = {0,0,0,1}; x = QUOTE(safezoneXAbs); y = QUOTE(safezoneY); w = QUOTE(safezoneXAbs - safezoneX); @@ -41,7 +41,7 @@ class GVAR(display) { class ArrowLeft: ctrlButton { idc = IDC_arrowMinus; text = "-"; - colorBackground[]={0,0,0,0.8}; + colorBackground[] = {0,0,0,0.8}; onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), -1)] call FUNC(buttonCargo)); fade = 1; enable = 0; @@ -54,7 +54,7 @@ class GVAR(display) { class ArrowRight: ArrowLeft { idc = IDC_arrowPlus; onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), 1)] call FUNC(buttonCargo)); - text="+"; + text = "+"; }; class blockLeftFrame: RscFrame { idc = IDC_blockLeftFrame; @@ -149,10 +149,10 @@ class GVAR(display) { class message: RscText { idc = IDC_message; fade = 1; - style=2; - shadow=0; - colorBackground[]={0,0,0,0.69999999}; - text=""; + style = 2; + shadow = 0; + colorBackground[] = {0,0,0,0.69999999}; + text = ""; x = QUOTE(0.5 - WIDTH_TOTAL / 2); y = QUOTE(safeZoneH + safezoneY - 25 * GRID_H); w = QUOTE(WIDTH_TOTAL); @@ -175,7 +175,6 @@ class GVAR(display) { h = QUOTE(7 * GRID_H); text = CSTRING(buttonHideText); sizeEx = QUOTE(5 * GRID_H); - shortcuts[] = {"0x0E"}; tooltip = CSTRING(buttonHideTooltip); onButtonClick = QUOTE([ctrlParent (_this select 0)] call FUNC(buttonHide)); }; @@ -260,7 +259,7 @@ class GVAR(display) { fade = 1; color[] = {1,1,1,1}; colorActive[] = {1,1,1,1}; - text="#(argb,8,8,3)color(1,1,1,1)"; + text = "#(argb,8,8,3)color(1,1,1,1)"; x = QUOTE(80 * GRID_W); y = QUOTE(0); w = QUOTE(12 * GRID_W); @@ -281,7 +280,7 @@ class GVAR(display) { y = QUOTE(0); w = QUOTE(47 * GRID_W); h = QUOTE(55 * GRID_H); - colorBackground[]={0.1,0.1,0.1,0.5}; + colorBackground[] = {0.1,0.1,0.1,0.5}; }; class statsStaticBackground2: ctrlStaticBackground { idc = -1; @@ -289,7 +288,7 @@ class GVAR(display) { y = QUOTE(0); w = QUOTE(47 * GRID_W); h = QUOTE(5 * GRID_H); - colorBackground[]={0.1,0.1,0.1,0.8}; + colorBackground[] = {0.1,0.1,0.1,0.8}; }; class statsTitle1: RscText { idc = IDC_statsTitle1; @@ -298,8 +297,8 @@ class GVAR(display) { 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}; + colorBackground[] = {0,0,0,0}; + colorText[] = {0.7,0.7,0.7,1}; sizeEx = QUOTE(5 * GRID_H); text = ""; }; @@ -310,7 +309,7 @@ class GVAR(display) { y = QUOTE(10 * GRID_H); w = QUOTE(45 * GRID_W); h = QUOTE(4 * GRID_H); - colorBackground[]={1,1,1,0.15}; + colorBackground[] = {1,1,1,0.15}; }; class statsBar1: ctrlProgress { idc = IDC_statsBar1; @@ -326,10 +325,10 @@ class GVAR(display) { }; class statsText1: RscText { idc = IDC_statsText1; - shadow=0; + shadow = 0; fade = 1; - colorShadow[]={1,1,1,1}; - colorText[]={0,0,0,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); @@ -396,7 +395,7 @@ class GVAR(display) { class statsBar5: statsBar1 { idc = IDC_statsBar5; y = QUOTE(50 * GRID_H); - colorBackground[]={1,1,1,0.15}; + colorBackground[] = {1,1,1,0.15}; }; class statsText5: statsText1 { idc = IDC_statsText5; @@ -406,8 +405,8 @@ class GVAR(display) { }; class statsButton: ctrlButton { idc = IDC_statsButton; - style= 2; - text=">"; + 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); @@ -417,10 +416,10 @@ class GVAR(display) { }; class statsPreviousPage: ctrlButton { idc = IDC_statsPreviousPage; - style= 2; - text="<"; - colorBackground[]={0,0,0,0}; - colorBackgroundDisabled[]= {0,0,0,0}; + 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); @@ -441,15 +440,15 @@ class GVAR(display) { y = QUOTE(safezoneY + 1.8 * GRID_H); w = QUOTE(25 * GRID_W); h = QUOTE(5 * GRID_H); - colorBackground[]={0,0,0,0}; - shadow=2; + 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"; + 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); @@ -466,13 +465,13 @@ class GVAR(display) { }; class leftTabContent: RscListBox { idc = IDC_leftTabContent; - colorBackground[]={0,0,0,0}; - colorSelectBackground[]={1,1,1,0.5}; - colorSelectBackground2[]={1,1,1,0.5}; - colorPictureSelected[]={1,1,1,1}; - colorSelect[]={1,1,1,1}; - colorSelect2[]={1,1,1,1}; - colorPictureRightSelected[]={1,1,1,1}; + colorBackground[] = {0,0,0,0}; + colorSelectBackground[] = {1,1,1,0.5}; + colorSelectBackground2[] = {1,1,1,0.5}; + colorPictureSelected[] = {1,1,1,1}; + colorSelect[] = {1,1,1,1}; + colorSelect2[] = {1,1,1,1}; + colorPictureRightSelected[] = {1,1,1,1}; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedLeft)); onSetFocus = QUOTE(GVAR(leftTabFocus) = true); onKillFocus = QUOTE(GVAR(leftTabFocus) = false); @@ -484,8 +483,8 @@ class GVAR(display) { }; class rightTabContent: leftTabContent { idc = IDC_rightTabContent; - drawSideArrows=1; - disableOverflow=1; + drawSideArrows = 1; + disableOverflow = 1; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedRight)); onSetFocus = QUOTE(GVAR(rightTabFocus) = true); onKillFocus = QUOTE(GVAR(rightTabFocus) = false); @@ -494,18 +493,18 @@ class GVAR(display) { }; class rightTabContentListnBox: RscListNBox { idc = IDC_rightTabContentListnBox; - colorBackground[]={0,0,0,0}; - colorSelectBackground[]={1,1,1,0.5}; - colorSelectBackground2[]={1,1,1,0.5}; - colorPictureSelected[]={1,1,1,1}; - colorSelect[]={1,1,1,1}; - colorSelect2[]={1,1,1,1}; - colorPictureRightSelected[]={1,1,1,1}; - columns[]={0.07, 0.15, 0.75}; + colorBackground[] = {0,0,0,0}; + colorSelectBackground[] = {1,1,1,0.5}; + colorSelectBackground2[] = {1,1,1,0.5}; + colorPictureSelected[] = {1,1,1,1}; + colorSelect[] = {1,1,1,1}; + colorSelect2[] = {1,1,1,1}; + colorPictureRightSelected[] = {1,1,1,1}; + columns[] = {0.07, 0.15, 0.75}; idcLeft = IDC_arrowMinus; idcRIght = IDC_arrowPlus; - drawSideArrows=1; - disableOverflow=1; + drawSideArrows = 1; + disableOverflow = 1; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedRightListnBox)); onSetFocus = QUOTE(GVAR(rightTabLnBFocus) = true); onKillFocus = QUOTE(GVAR(rightTabLnBFocus) = false); @@ -551,7 +550,7 @@ class GVAR(display) { class leftSearchbarButton: ctrlButtonPicture { idc = IDC_leftSearchbarButton; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; - colorBackground[]={0,0,0,0.5}; + colorBackground[] = {0,0,0,0.5}; onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_leftSearchbar)] call FUNC(handleSearchbar)); x = QUOTE(safezoneX + 87 * GRID_W); y = QUOTE(safezoneY + 1.8 * GRID_H); @@ -578,9 +577,9 @@ class GVAR(display) { class controls { class iconBackgroundPrimaryWeapon: ctrlStaticBackground { idc = IDC_iconBackgroundPrimaryWeapon; - fade=1; - enable=0; - colorBackground[]={0,0,0,1}; + fade = 1; + enable = 0; + colorBackground[] = {0,0,0,1}; x = QUOTE(0); y = QUOTE(0 * GRID_H); w = QUOTE(12 * GRID_W); @@ -588,10 +587,10 @@ class GVAR(display) { }; class buttonPrimaryWeapon: RscButtonArsenal { idc = IDC_buttonPrimaryWeapon; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\PrimaryWeapon_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_PrimaryWeapon"; + 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)); - colorBackground[]={0,0,0,0.5}; + colorBackground[] = {0,0,0,0.5}; x = QUOTE(0 * GRID_W); y = QUOTE(0 * GRID_H); w = QUOTE(9 * GRID_W); @@ -603,8 +602,8 @@ class GVAR(display) { }; class buttonHandgun: buttonPrimaryWeapon { idc = IDC_buttonHandgun; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Handgun_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_Handgun"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Handgun_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Handgun"; y = QUOTE(10 * GRID_H); }; class iconBackgroundSecondaryWeapon: IconBackgroundPrimaryWeapon { @@ -613,8 +612,8 @@ class GVAR(display) { }; class buttonSecondaryWeapon: buttonPrimaryWeapon { idc = IDC_buttonSecondaryWeapon; - tooltip="$STR_A3_RscDisplayArsenal_tab_SecondaryWeapon"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\SecondaryWeapon_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_SecondaryWeapon"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\SecondaryWeapon_ca.paa"; y = QUOTE(20 * GRID_H); }; class iconBackgroundHeadgear: IconBackgroundPrimaryWeapon { @@ -623,8 +622,8 @@ class GVAR(display) { }; class buttonHeadgear: buttonPrimaryWeapon { idc = IDC_buttonHeadgear; - tooltip="$STR_A3_RscDisplayArsenal_tab_Headgear"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Headgear_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Headgear"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Headgear_ca.paa"; y = QUOTE(30 * GRID_H); }; class iconBackgroundUniform: IconBackgroundPrimaryWeapon { @@ -633,8 +632,8 @@ class GVAR(display) { }; class buttonUniform: buttonPrimaryWeapon { idc = IDC_buttonUniform; - tooltip="$STR_A3_RscDisplayArsenal_tab_Uniform"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Uniform_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Uniform"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Uniform_ca.paa"; y = QUOTE(40 * GRID_H); }; class iconBackgroundVest: IconBackgroundPrimaryWeapon { @@ -643,8 +642,8 @@ class GVAR(display) { }; class buttonVest: buttonPrimaryWeapon { idc = IDC_buttonVest; - tooltip="$STR_A3_RscDisplayArsenal_tab_Vest"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Vest_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Vest"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Vest_ca.paa"; y = QUOTE(50 * GRID_H); }; class iconBackgroundBackpack: IconBackgroundPrimaryWeapon { @@ -653,8 +652,8 @@ class GVAR(display) { }; class buttonBackpack: buttonPrimaryWeapon { idc = IDC_buttonBackpack; - tooltip="$STR_A3_RscDisplayArsenal_tab_Backpack"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Backpack_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Backpack"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Backpack_ca.paa"; y = QUOTE(60 * GRID_H); }; class iconBackgroundGoggles: IconBackgroundPrimaryWeapon { @@ -663,8 +662,8 @@ class GVAR(display) { }; class buttonGoggles: buttonPrimaryWeapon { idc = IDC_buttonGoggles; - tooltip="$STR_A3_RscDisplayArsenal_tab_Goggles"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Goggles_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Goggles"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Goggles_ca.paa"; y = QUOTE(70 * GRID_H); }; class iconBackgroundNVG: IconBackgroundPrimaryWeapon { @@ -673,8 +672,8 @@ class GVAR(display) { }; class buttonNVG: buttonPrimaryWeapon { idc = IDC_buttonNVG; - tooltip="$STR_A3_RscDisplayArsenal_tab_NVGs"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\NVGs_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_NVGs"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\NVGs_ca.paa"; y = QUOTE(80 * GRID_H); }; class iconBackgroundBinoculars: IconBackgroundPrimaryWeapon { @@ -683,8 +682,8 @@ class GVAR(display) { }; class buttonBinoculars: buttonPrimaryWeapon { idc = IDC_buttonBinoculars; - tooltip="$STR_A3_RscDisplayArsenal_tab_Binoculars"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Binoculars_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Binoculars"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Binoculars_ca.paa"; y = QUOTE(90 * GRID_H); }; class iconBackgroundMap: IconBackgroundPrimaryWeapon { @@ -693,8 +692,8 @@ class GVAR(display) { }; class buttonMap: buttonPrimaryWeapon { idc = IDC_buttonMap; - tooltip="$STR_A3_RscDisplayArsenal_tab_Map"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Map_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Map"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Map_ca.paa"; y = QUOTE(100 * GRID_H); }; class iconBackgroundGPS: IconBackgroundPrimaryWeapon { @@ -703,8 +702,8 @@ class GVAR(display) { }; class buttonGPS: buttonPrimaryWeapon { idc = IDC_buttonGPS; - tooltip="$STR_A3_RscDisplayArsenal_tab_GPS"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\GPS_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_GPS"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\GPS_ca.paa"; y = QUOTE(110 * GRID_H); }; class iconBackgroundRadio: IconBackgroundPrimaryWeapon { @@ -713,8 +712,8 @@ class GVAR(display) { }; class buttonRadio: buttonPrimaryWeapon { idc = IDC_buttonRadio; - tooltip="$STR_A3_RscDisplayArsenal_tab_Radio"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Radio_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Radio"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Radio_ca.paa"; y = QUOTE(120 * GRID_H); }; class iconBackgroundCompass: IconBackgroundPrimaryWeapon { @@ -723,8 +722,8 @@ class GVAR(display) { }; class buttonCompass: buttonPrimaryWeapon { idc = IDC_buttonCompass; - tooltip="$STR_A3_RscDisplayArsenal_tab_Compass"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Compass_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Compass"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Compass_ca.paa"; y = QUOTE(130 * GRID_H); }; class iconBackgroundWatch: IconBackgroundPrimaryWeapon { @@ -733,8 +732,8 @@ class GVAR(display) { }; class buttonWatch: buttonPrimaryWeapon { idc = IDC_buttonWatch; - tooltip="$STR_A3_RscDisplayArsenal_tab_Watch"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Watch_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Watch"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Watch_ca.paa"; y = QUOTE(140 * GRID_H); }; class iconBackgroundFace: IconBackgroundPrimaryWeapon { @@ -743,8 +742,8 @@ class GVAR(display) { }; class buttonFace: buttonPrimaryWeapon { idc = IDC_buttonFace; - tooltip="$STR_A3_RscDisplayArsenal_tab_Face"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Face_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Face"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Face_ca.paa"; y = QUOTE(150 * GRID_H); }; class iconBackgroundVoice: IconBackgroundPrimaryWeapon { @@ -753,8 +752,8 @@ class GVAR(display) { }; class buttonVoice: buttonPrimaryWeapon { idc = IDC_buttonVoice; - tooltip="$STR_A3_RscDisplayArsenal_tab_Voice"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Voice_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Voice"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Voice_ca.paa"; y = QUOTE(160 * GRID_H); }; class iconBackgroundInsigna: IconBackgroundPrimaryWeapon { @@ -763,17 +762,17 @@ class GVAR(display) { }; class buttonInsigna: buttonPrimaryWeapon { idc = IDC_buttonInsignia; - tooltip="$STR_A3_RscDisplayArsenal_tab_Insignia"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Insignia_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_Insignia"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\Insignia_ca.paa"; y = QUOTE(170 * GRID_H); }; }; }; class iconBackgroundOptic: ctrlStaticBackground { idc = IDC_iconBackgroundOptic; - colorBackground[]={0,0,0,1}; - fade=1; - enable=0; + colorBackground[] = {0,0,0,1}; + fade = 1; + enable = 0; x = QUOTE(safezoneW + safezoneX - 13 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); w = QUOTE(12 * GRID_W); @@ -781,10 +780,10 @@ class GVAR(display) { }; class buttonOptic: RscButtonArsenal { idc = IDC_buttonOptic; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemOptic"; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemOptic_ca.paa"; + 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)); - colorBackground[]={0,0,0,0.5}; + colorBackground[] = {0,0,0,0.5}; x = QUOTE(safezoneW + safezoneX - 10 * GRID_W); y = QUOTE(safezoneY + 8 * GRID_H); w = QUOTE(9 * GRID_W); @@ -796,8 +795,8 @@ class GVAR(display) { }; class buttonItemAcc: buttonOptic { idc = IDC_buttonItemAcc; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemAcc"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemAcc_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemAcc"; y = QUOTE(safezoneY + 18 * GRID_H); }; class iconBackgroundMuzzle: iconBackgroundOptic { @@ -806,8 +805,8 @@ class GVAR(display) { }; class buttonMuzzle: buttonOptic { idc = IDC_buttonMuzzle; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemMuzzle"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemMuzzle_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemMuzzle"; y = QUOTE(safezoneY + 28 * GRID_H); }; class iconBackgroundBipod: iconBackgroundOptic { @@ -816,8 +815,8 @@ class GVAR(display) { }; class buttonBipod: buttonOptic { idc = IDC_buttonBipod; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_ItemBipod"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\ItemBipod_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_ItemBipod"; y = QUOTE(safezoneY + 38 * GRID_H); }; class iconBackgroundCurrentMag: iconBackgroundOptic { @@ -826,8 +825,8 @@ class GVAR(display) { }; class buttonCurrentMag: buttonOptic { idc = IDC_buttonCurrentMag; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; - tooltip= CSTRING(buttonCurrentMagTooltip); + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; + tooltip = CSTRING(buttonCurrentMagTooltip); y = QUOTE(safezoneY + 48 * GRID_H); }; class iconBackgroundCurrentMag2: iconBackgroundOptic { @@ -836,8 +835,8 @@ class GVAR(display) { }; class buttonCurrentMag2: buttonOptic { idc = IDC_buttonCurrentMag2; - text= QPATHTOF(data\iconSecondaryMuzzle); - tooltip= CSTRING(buttonCurrentMag2Tooltip); + text = QPATHTOF(data\iconSecondaryMuzzle); + tooltip = CSTRING(buttonCurrentMag2Tooltip); y = QUOTE(safezoneY + 58 * GRID_H); }; class iconBackgroundMag: iconBackgroundOptic { @@ -846,8 +845,8 @@ class GVAR(display) { }; class buttonMag: buttonOptic { idc = IDC_buttonMag; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMag"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMag_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMag"; y = QUOTE(safezoneY + 48 * GRID_H); }; class iconBackgroundMagALL: iconBackgroundOptic { @@ -856,8 +855,8 @@ class GVAR(display) { }; class buttonMagALL: buttonOptic { idc = IDC_buttonMagALL; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMagAll"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMagAll_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMagAll"; y = QUOTE(safezoneY + 58 * GRID_H); }; class iconBackgroundThrow: iconBackgroundOptic { @@ -866,8 +865,8 @@ class GVAR(display) { }; class buttonThrow: buttonOptic { idc = IDC_buttonThrow; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoThrow"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoThrow_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoThrow"; y = QUOTE(safezoneY + 68 * GRID_H); }; class iconBackgroundPut: iconBackgroundOptic { @@ -876,8 +875,8 @@ class GVAR(display) { }; class buttonPut: buttonOptic { idc = IDC_buttonPut; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoPut"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoPut_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoPut"; y = QUOTE(safezoneY + 78 * GRID_H); }; class iconBackgroundMisc: iconBackgroundOptic { @@ -886,8 +885,8 @@ class GVAR(display) { }; class buttonMisc: buttonOptic { idc = IDC_buttonMisc; - text="\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa"; - tooltip="$STR_A3_RscDisplayArsenal_tab_CargoMisc"; + text = "\A3\Ui_f\data\GUI\Rsc\RscDisplayArsenal\CargoMisc_ca.paa"; + tooltip = "$STR_A3_RscDisplayArsenal_tab_CargoMisc"; y = QUOTE(safezoneY + 88 * GRID_H); }; @@ -895,10 +894,10 @@ class GVAR(display) { idc = IDC_buttonRemoveAll; text = QPATHTOF(data\iconClearContainer.paa); tooltip = CSTRING(buttonClearContainerTooltip); - colorBackground[]={0,0,0,0.5}; + colorBackground[] = {0,0,0,0.5}; onButtonClick = QUOTE(ctrlParent (_this select 0) call FUNC(buttonClearAll)); - fade=1; - enable=0; + fade = 1; + enable = 0; x = QUOTE(safezoneW + safezoneX - 11 * GRID_W); y = QUOTE(safeZoneH + safezoneY - 29 * GRID_H); w = QUOTE(9 * GRID_W); @@ -947,9 +946,9 @@ class GVAR(loadoutsDisplay) { }; class contentPanel: RscListnBox { idc = IDC_contentPanel; - columns[]={0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90}; - drawSideArrows=0; - disableOverflow=1; + columns[] = {0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90}; + drawSideArrows = 0; + disableOverflow = 1; 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)); @@ -961,17 +960,17 @@ class GVAR(loadoutsDisplay) { sizeEx = QUOTE(7 * GRID_H); }; class textTitle: RscText { - idc= -1; - text="$STR_DISP_GAME_NAME"; + idc = -1; + text = "$STR_DISP_GAME_NAME"; x = QUOTE(0 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(15 * GRID_W); h = QUOTE(5 * GRID_H); sizeEx = QUOTE(5 * GRID_H); - colorBackground[]={0,0,0,0.2}; + colorBackground[] = {0,0,0,0.2}; }; class textEditBox: ctrlEdit { - idc= IDC_textEditBox; + idc = IDC_textEditBox; x = QUOTE(15 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); w = QUOTE(65 * GRID_W); @@ -992,7 +991,7 @@ class GVAR(loadoutsDisplay) { class loadoutsSearchbarButton: ctrlButtonPicture { idc = -1; text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa"; - colorBackground[]={0,0,0,0.5}; + colorBackground[] = {0,0,0,0.5}; onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), ctrlParent (_this select 0) displayCtrl IDC_loadoutsSearchbar)] call FUNC(handleLoadoutsSearchbar)); x = QUOTE(155 * GRID_W); y = QUOTE(safezoneH - (51 * GRID_H)); @@ -1005,8 +1004,8 @@ class GVAR(loadoutsDisplay) { y = QUOTE(safezoneH - (44 * GRID_H)); w = QUOTE(30 * GRID_W); h = QUOTE(10 * GRID_H); - text= CSTRING(buttonSaveText); - tooltip= CSTRING(buttonSaveTooltip); + 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)); colorBackground[] = {0,0,0,0.8}; @@ -1021,22 +1020,22 @@ class GVAR(loadoutsDisplay) { class buttonLoad: buttonSave { idc = IDC_buttonLoad; x = QUOTE(65 * GRID_W); - text= CSTRING(buttonLoadText); - tooltip= CSTRING(buttonLoadTooltip); + text = CSTRING(buttonLoadText); + tooltip = CSTRING(buttonLoadTooltip); 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); + text = CSTRING(buttonSharePrivateText); + tooltip = CSTRING(buttonShareTooltip); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(buttonLoadoutsShare)); }; class buttonDelete: buttonSave { idc = IDC_buttonDelete; x = QUOTE(130 * GRID_W); - text= CSTRING(buttonDeleteText); - tooltip= CSTRING(buttonDeleteTooltip); + 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)); }; @@ -1049,9 +1048,8 @@ class GVAR(loadoutsDisplay) { w = QUOTE(30 * GRID_W); h = QUOTE(7 * GRID_H); sizeEx = QUOTE(5 * GRID_H); - text= CSTRING(buttonCloseText); - shortcuts[]= {"0x01"}; - tooltip= ""; + text = CSTRING(buttonCloseText); + tooltip = ""; onButtonClick = QUOTE(ctrlParent (_this select 0) closeDisplay 2); }; class buttonBar: ctrlControlsGroupNoScrollbars { @@ -1077,8 +1075,8 @@ class GVAR(loadoutsDisplay) { w = QUOTE(52 * GRID_W); h = QUOTE(7 * GRID_H); sizeEx = QUOTE(5 * GRID_H); - text= CSTRING(tabMyLoadoutsText); - tooltip= CSTRING(tabMyLoadoutsTooltip); + text = CSTRING(tabMyLoadoutsText); + tooltip = CSTRING(tabMyLoadoutsTooltip); onButtonClick = QUOTE([ARR_2(ctrlParent (_this select 0), _this select 0)] call FUNC(loadoutsChangeTab)); }; class buttonDefaultLoadoutsBackground: buttonMyLoadoutsBackground { @@ -1088,8 +1086,8 @@ class GVAR(loadoutsDisplay) { class buttonDefaultLoadouts: buttonMyLoadouts { idc = IDC_buttonDefaultLoadouts; x = QUOTE(54.5 * GRID_W); - text= CSTRING(tabDefaultLoadoutsText); - tooltip= CSTRING(tabDefaultLoadoutsTooltip); + text = CSTRING(tabDefaultLoadoutsText); + tooltip = CSTRING(tabDefaultLoadoutsTooltip); }; class buttonSharedLoadoutsBackground: buttonMyLoadoutsBackground { idc = IDC_buttonSharedLoadoutsBackground; @@ -1098,8 +1096,8 @@ class GVAR(loadoutsDisplay) { class buttonSharedLoadouts: buttonMyLoadouts { idc = IDC_buttonSharedLoadouts; x = QUOTE(109 * GRID_W); - text= CSTRING(tabSharedLoadoutsText); - tooltip= CSTRING(tabSharedLoadoutsTooltip); + text = CSTRING(tabSharedLoadoutsText); + tooltip = CSTRING(tabSharedLoadoutsTooltip); }; }; }; diff --git a/addons/ballistics/ACE_Arsenal_Stats.hpp b/addons/ballistics/ACE_Arsenal_Stats.hpp index 9e4982656b3..67e7d246e3b 100644 --- a/addons/ballistics/ACE_Arsenal_Stats.hpp +++ b/addons/ballistics/ACE_Arsenal_Stats.hpp @@ -59,7 +59,7 @@ class EGVAR(arsenal,stats) { }; class ACE_weaponMuzzleVelocity: statBase { scope = 2; - priority = 3; + priority = 1; stats[] = {"initSpeed"}; displayName= CSTRING(statMuzzleVelocity); showText = 1; diff --git a/addons/gforces/ACE_Arsenal_Stats.hpp b/addons/gforces/ACE_Arsenal_Stats.hpp index 4148ba5fe2b..372f5af782c 100644 --- a/addons/gforces/ACE_Arsenal_Stats.hpp +++ b/addons/gforces/ACE_Arsenal_Stats.hpp @@ -2,7 +2,7 @@ class EGVAR(arsenal,stats) { class statBase; class ACE_gReduction: statBase { scope = 2; - priority = 1; + priority = 1.7; stats[] = {"ACE_GForceCoef"}; displayName = CSTRING(statGReduction); showBar = 1; diff --git a/addons/hearing/ACE_Arsenal_Stats.hpp b/addons/hearing/ACE_Arsenal_Stats.hpp index cc9e0488238..9e47b0a4936 100644 --- a/addons/hearing/ACE_Arsenal_Stats.hpp +++ b/addons/hearing/ACE_Arsenal_Stats.hpp @@ -11,7 +11,7 @@ class EGVAR(arsenal,stats) { }; class ACE_volumeMuffling: statBase { scope = 2; - priority = 1; + priority = 1.75; stats[] = {QGVAR(lowerVolume)}; displayName= CSTRING(statHearingLowerVolume); showBar = 1; diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 419dcd4245c..d01b94c4153 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -135,7 +135,7 @@ Examples: ACE Arsenal has 2 new config entries for items: - `ace_arsenal_hide`: `0`(shown) or `1` (hidden), used to hide items from ACE Arsenal or `-1` (forced show), for magazines. -- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout and displaying it in the arsenal. Supports configs in "CfgWeapons" (e.g. Maps, Compasses, Watches, GPS / UAV Terminals, Radios, NVGs, Uniforms, Vests - however no Primary, Secondary, Handgun or Launcher weapons are supported), "CfgMagazines" (any magazine) and "CfgVehicles" (e.g. Backpacks). Item that replaces must be of the same config type as the original item. +- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout and displaying it in the arsenal. Supports configs in "CfgWeapons" (e.g. Maps, Compasses, Watches, GPS / UAV Terminals, Radios, NVGs, Uniforms, Vests - however no Primary, Secondary, Handgun, Launcher weapons or weapon attachments are supported), "CfgMagazines" (any magazine) and "CfgVehicles" (e.g. Backpacks). Item that replaces must be of the same config type as the original item. Both of them are optional. @@ -212,7 +212,7 @@ The arguments passed to the bar, text and condition statements are: 4 | Show bar / show text bools | Array of booleans | Required 4.1 | Show bar | Boolean | Required 4.2 | Show text | Boolean | Required -5 | Array of statements | Array of arrays | Required +5 | Array of statements | Array of code | Required 5.1 | Bar code | Code | Required 5.2 | Text code | Code | Required 5.3 | Condition | Code | Required @@ -346,6 +346,18 @@ Example: Sorting method IDs are unique and are generated in the same fashion as the stat IDs (see `5.3 Removing stats via a function`). +### 6.3 Removing sorting methods via a function + +`ace_arsenal_fnc_removeSort` + +| | Argument | Type | Optional (default value) +---| -------- | ---- | ------------------------ +0 | Array of IDs | Array | Required + +Sorting method IDs are unique and are generated in the same fashion as the stat IDs (see `5.3 Removing stats via a function`). + +For config added sorts the classname is used, for function added ones the string provided is used. + ### 6.4 Sort tab numbers The same numbers are used for sorting methods as for stats (see `5.4 Stat tab numbers`). From 3d6647bd184040b67437260d9dc86ae26abef4fc Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 9 Jul 2023 21:31:52 +0200 Subject: [PATCH 12/24] Update fnc_replaceUniqueItemsLoadout.sqf --- .../functions/fnc_replaceUniqueItemsLoadout.sqf | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf index 82b00208b3e..9155ea98d73 100644 --- a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -45,10 +45,14 @@ private _cfgVehicles = configFile >> "CfgVehicles"; { // Magazines if (_forEachIndex in [4, 5]) then { - _uniqueBaseCfgText = (getText (_cfgMagazines >> _x >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + _x params [["_magazine", ""], "_count"]; - if (_uniqueBaseCfgText != "") then { - _weaponsInfo set [_forEachIndex, _uniqueBaseCfgText]; + if (_magazine != "") then { + _uniqueBaseCfgText = (getText (_cfgMagazines >> _magazine >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _weaponsInfo set [_forEachIndex, [_uniqueBaseCfgText, _count]]; + }; }; } else { // Other From fdf8bcac26c74411470073f4530f17f91594f782 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 9 Jul 2023 21:48:04 +0200 Subject: [PATCH 13/24] Update fnc_onSelChangedLeft.sqf --- addons/arsenal/functions/fnc_onSelChangedLeft.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 6347be48ef5..875aa4e94a4 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -307,7 +307,7 @@ switch (GVAR(currentLeftPanel)) do { private _index = count _uniformItems - 1; // Remove any items that can't fit in the container (this prevents overloading) - while {loadUniform GVAR(center) > 1 || {_index < 0}} do { + while {loadUniform GVAR(center) > 1 && {_index >= 0}} do { GVAR(center) removeItemFromUniform (_uniformItems select _index); DEC(_index); }; @@ -348,7 +348,7 @@ switch (GVAR(currentLeftPanel)) do { private _index = count _vestItems - 1; // Remove any items that can't fit in the container (this prevents overloading) - while {loadVest GVAR(center) > 1 || {_index < 0}} do { + while {loadVest GVAR(center) > 1 && {_index >= 0}} do { GVAR(center) removeItemFromVest (_vestItems select _index); DEC(_index); }; @@ -386,7 +386,7 @@ switch (GVAR(currentLeftPanel)) do { private _index = count _backpackItems - 1; // Remove any items that can't fit in the container (this prevents overloading) - while {loadBackpack GVAR(center) > 1 || {_index < 0}} do { + while {loadBackpack GVAR(center) > 1 && {_index >= 0}} do { GVAR(center) removeItemFromBackpack (_backpackItems select _index); DEC(_index); }; From dbdba9ae8f60ae8f418c070dc83325fbbb8190d3 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 9 Jul 2023 22:36:03 +0200 Subject: [PATCH 14/24] Update fnc_scanConfig.sqf --- addons/arsenal/functions/fnc_scanConfig.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 0374a37a6cd..b980d50d63b 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -209,7 +209,7 @@ private _faceCategory = ""; { if (getNumber (_x >> "disabled") == 0 && {getText (_x >> "head") != ""} && {configName _x != "Default"}) then { - _dlcName = _x call EFUNC(common,ggetAddon); + _dlcName = _x call EFUNC(common,getAddon); _modPicture = ""; if (_dlcName != "") then { From 4561ccd5caf33b31e5f454dd8ce315447c10646c Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 11 Jul 2023 09:14:19 -0700 Subject: [PATCH 15/24] Update docs/wiki/framework/arsenal-framework.md Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- docs/wiki/framework/arsenal-framework.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index d01b94c4153..54c3a1d9541 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -139,7 +139,8 @@ ACE Arsenal has 2 new config entries for items: Both of them are optional. -- `baseWeapon`: Class name that is used to display an item in the arsenal. This property can be applied to any weapon or weapon attachment in "CfgWeapons". +- `baseWeapon`: Class name that is used to display an item in the arsenal. This property can be applied to any weapon or weapon attachment in `CfgWeapons`. +- `ACE_isUnique`: Classes in `CfgMagazines` with this property set to `1` will be treated and shown by the Arsenal as Misc. Items. Used for items with attached data that needs to be kept track of, such as Notepads or Spare Barrels. ## 4. Default loadouts From fa48fef7f29cca6eb10b1c265760e3b200a61292 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 11 Jul 2023 18:16:30 +0200 Subject: [PATCH 16/24] Minor cleanup --- addons/arsenal/functions/fnc_addVirtualItems.sqf | 4 +--- docs/wiki/framework/arsenal-framework.md | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index caff60bb7e2..c9c1c71879b 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -72,14 +72,12 @@ if (_items isEqualType true) then { // Remove any invalid/non-existing items _items = _items - [""]; + private _configItems = uiNamespace getVariable QGVAR(configItems); private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); // Remove any items not found by the arsenal _items = _items select {_x in _configItemsFlat}; - private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); - private _configItems = uiNamespace getVariable QGVAR(configItems); - // https://community.bistudio.com/wiki/Arma_3:_Characters_And_Gear_Encoding_Guide#Character_configuration // https://github.com/acemod/ACE3/pull/9040#issuecomment-1597748331 { diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 54c3a1d9541..64323a302ac 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -135,7 +135,7 @@ Examples: ACE Arsenal has 2 new config entries for items: - `ace_arsenal_hide`: `0`(shown) or `1` (hidden), used to hide items from ACE Arsenal or `-1` (forced show), for magazines. -- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout and displaying it in the arsenal. Supports configs in "CfgWeapons" (e.g. Maps, Compasses, Watches, GPS / UAV Terminals, Radios, NVGs, Uniforms, Vests - however no Primary, Secondary, Handgun, Launcher weapons or weapon attachments are supported), "CfgMagazines" (any magazine) and "CfgVehicles" (e.g. Backpacks). Item that replaces must be of the same config type as the original item. +- `ace_arsenal_uniqueBase`: Class name of the item that ACE Arsenal will replace it with when saving a loadout and displaying it in the arsenal. Supports configs in `CfgWeapons` (e.g. Maps, Compasses, Watches, GPS / UAV Terminals, Radios, NVGs, Uniforms, Vests - however no Primary, Secondary, Handgun, Launcher weapons or weapon attachments are supported), `CfgMagazines` (any magazine) and `CfgVehicles` (e.g. Backpacks). Item that replaces must be of the same config type as the original item. Both of them are optional. From 98a9c82b800ecbd5a1dc00dfc0268c77ea571f4d Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 11 Jul 2023 22:49:57 +0200 Subject: [PATCH 17/24] Baseweapon filtering --- .../arsenal/functions/fnc_addVirtualItems.sqf | 17 ++++++++++------- .../functions/fnc_removeVirtualItems.sqf | 5 +++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index c9c1c71879b..68f30bacc34 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -75,6 +75,9 @@ if (_items isEqualType true) then { private _configItems = uiNamespace getVariable QGVAR(configItems); private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); + // Convert all items to their baseWeapon + _items = _items apply {if (_x in _configItemsFlat) then {_x} else {_x call FUNC(baseWeapon)}}; + // Remove any items not found by the arsenal _items = _items select {_x in _configItemsFlat}; @@ -84,27 +87,27 @@ if (_items isEqualType true) then { switch (true) do { // Weapons case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS)): { - ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_PRIMARY_WEAPONS) set [_x, nil]; }; case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS)): { - ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_HANDGUN_WEAPONS) set [_x, nil]; }; case (_x in ((_configItems get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS)): { - ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_WEAPONS) get IDX_VIRT_SECONDARY_WEAPONS) set [_x, nil]; }; // Weapon attachments case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)): { - ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x, nil]; }; case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)): { - ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x, nil]; }; case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)): { - ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x, nil]; }; case (_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)): { - ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x call FUNC(baseWeapon), nil]; + ((_cargo get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x, nil]; }; // Other diff --git a/addons/arsenal/functions/fnc_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf index e6a8d4c5707..215508a287d 100644 --- a/addons/arsenal/functions/fnc_removeVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -40,6 +40,11 @@ if (_items isEqualType true) then { // Remove any invalid/non-existing items _items = _items - [""]; + private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); + + // Convert all items to their baseWeapon + _items = _items apply {if (_x in _configItemsFlat) then {_x} else {_x call FUNC(baseWeapon)}}; + // Remove items from lists { switch (true) do { From 13357dec00367064e2556a403012f3fbb1e6524a Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Thu, 13 Jul 2023 22:17:28 +0200 Subject: [PATCH 18/24] Improvements + better unique items support --- .../functions/fnc_attributeAddCompatible.sqf | 4 +- .../functions/fnc_attributeAddItems.sqf | 2 +- .../arsenal/functions/fnc_fillLeftPanel.sqf | 30 +-- .../arsenal/functions/fnc_fillRightPanel.sqf | 153 +++++++------- .../functions/fnc_onSelChangedRight.sqf | 116 +++++++++-- addons/arsenal/functions/fnc_scanConfig.sqf | 30 +-- .../functions/fnc_updateUniqueItemsList.sqf | 196 +++++++++++------- 7 files changed, 331 insertions(+), 200 deletions(-) diff --git a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf index 88e5c55ec17..feac294d504 100644 --- a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf +++ b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf @@ -51,7 +51,7 @@ if (_category == IDX_CAT_ITEMS_ALL) then { if (_x in (_configItems get IDX_VIRT_ITEMS_ALL)) then { _itemsToAdd set [_x, nil]; }; - } forEach _compatibleMagazines; + } forEach (keys _compatibleMagazines); } else { private _attachmentCategory = _category - 4; private _filter = ["optic", "pointer", "muzzle", "bipod"] select _attachmentCategory; @@ -72,7 +72,7 @@ if (_category == IDX_CAT_ITEMS_ALL) then { ) then { _itemsToAdd set [_x, nil]; }; - } forEach _compatibleItems; + } forEach (keys _compatibleItems); }; // Only take items that can be found by default in the arsenal diff --git a/addons/arsenal/functions/fnc_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf index a0409a8cab9..1d163afbcf8 100644 --- a/addons/arsenal/functions/fnc_attributeAddItems.sqf +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -128,7 +128,7 @@ private _config = _cfgClass; _listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]]; _listbox lnbSetColor [[_index, 2], [1, 1, 1, _alpha]]; }; -} forEach _categoryItems; +} forEach (keys _categoryItems); // Sort alphabetically _listbox lnbSort [1, false]; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index 58d3d97b9bb..a37210e4a2d 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -55,7 +55,7 @@ private _selectedItem = switch (true) do { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _index); + } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _index)); GVAR(currentItems) select _index }; @@ -73,7 +73,7 @@ private _selectedItem = switch (true) do { case IDC_buttonUniform: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIFORM); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIFORM)); GVAR(currentItems) select IDX_CURR_UNIFORM }; @@ -81,7 +81,7 @@ private _selectedItem = switch (true) do { case IDC_buttonVest: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_VEST); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_VEST)); GVAR(currentItems) select IDX_CURR_VEST }; @@ -89,7 +89,7 @@ private _selectedItem = switch (true) do { case IDC_buttonBackpack: { { ["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_BACKPACK); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_BACKPACK)); GVAR(currentItems) select IDX_CURR_BACKPACK }; @@ -115,7 +115,7 @@ private _selectedItem = switch (true) do { case IDC_buttonHeadgear: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_HEADGEAR); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_HEADGEAR)); GVAR(currentItems) select IDX_CURR_HEADGEAR }; @@ -123,7 +123,7 @@ private _selectedItem = switch (true) do { case IDC_buttonGoggles: { { ["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_GOGGLES); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_GOGGLES)); GVAR(currentItems) select IDX_CURR_GOGGLES }; @@ -131,7 +131,7 @@ private _selectedItem = switch (true) do { case IDC_buttonNVG: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_NVG); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_NVG)); GVAR(currentItems) select IDX_CURR_NVG }; @@ -139,7 +139,7 @@ private _selectedItem = switch (true) do { case IDC_buttonBinoculars: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_BINO); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_BINO)); GVAR(currentItems) select IDX_CURR_BINO }; @@ -147,7 +147,7 @@ private _selectedItem = switch (true) do { case IDC_buttonMap: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_MAP); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_MAP)); GVAR(currentItems) select IDX_CURR_MAP }; @@ -155,7 +155,7 @@ private _selectedItem = switch (true) do { case IDC_buttonCompass: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_COMPASS); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_COMPASS)); GVAR(currentItems) select IDX_CURR_COMPASS }; @@ -163,7 +163,7 @@ private _selectedItem = switch (true) do { case IDC_buttonRadio: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_RADIO); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_RADIO)); GVAR(currentItems) select IDX_CURR_RADIO }; @@ -171,7 +171,7 @@ private _selectedItem = switch (true) do { case IDC_buttonWatch: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_WATCH); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_WATCH)); GVAR(currentItems) select IDX_CURR_WATCH }; @@ -179,7 +179,7 @@ private _selectedItem = switch (true) do { case IDC_buttonGPS: { { ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (GVAR(virtualItems) get IDX_VIRT_COMMS); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_COMMS)); GVAR(currentItems) select IDX_CURR_COMMS }; @@ -201,7 +201,7 @@ private _selectedItem = switch (true) do { // Voices case IDC_buttonVoice: { { - ["CfgVoice", configName _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); + ["CfgVoice", _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); } forEach (uiNamespace getVariable QGVAR(voiceCache)); GVAR(currentVoice) @@ -210,7 +210,7 @@ private _selectedItem = switch (true) do { case IDC_buttonInsignia: { // Insignia from config { - ["CfgUnitInsignia", configName _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); + ["CfgUnitInsignia", _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); } forEach (uiNamespace getVariable QGVAR(insigniaCache)); private _displayName = ""; diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index eeaef11e771..c1ca01bd13f 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -41,10 +41,9 @@ if (!(ctrlShown _searchbarCtrl) || {ctrlFade _searchbarCtrl > 0}) then { private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgWeapons = configFile >> "CfgWeapons"; -private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); private _rightPanelCache = uiNamespace getVariable QGVAR(rightPanelCache); -private _fnc_fill_right_Container = { +private _fnc_fillRightContainer = { params ["_configCategory", "_className", "_hasItemInfo", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; // If item is not in the arsenal, it must be unique @@ -58,7 +57,7 @@ private _fnc_fill_right_Container = { private _configPath = configFile >> _configCategory >> _className; // "Misc. items" magazines (e.g. spare barrels, intel, photos) - if (_className in _magazineMiscItems) then { + if (_className in (uiNamespace getVariable QGVAR(magazineMiscItems))) then { _configPath = _cfgMagazines >> _className; _hasItemInfo = false; }; @@ -113,10 +112,10 @@ _ctrlPanel lbSetCurSel -1; _listnBox lbSetCurSel -1; // Retrieve compatible items -private _compatibleItems = []; private _itemToCheck = ""; -private _allCompatibleMags = []; +private _compatibleItems = []; private _compatibleMagsMuzzle = []; +private _compatibleMagsAll = createHashMap; switch (GVAR(currentLeftPanel)) do { // If weapons or binoculars are chosen, get their compatible magazines & items @@ -166,16 +165,9 @@ switch (GVAR(currentLeftPanel)) do { // This is for the "compatible magazines" tab when a container is open if (_ctrlIDC == IDC_buttonMag) then { - private _muzzles = []; - - // Get all compatibles magazines with unit's weapons + // Get all compatibles magazines with unit's weapons (including compatible magazines that aren't in configItems) { - _muzzles = _x call CBA_fnc_getMuzzles; - - // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) - // Assumption: One weapon can have two muzzles maximum - _allCompatibleMags append (compatibleMagazines [_x, _muzzles param [0, ""]]); - _allCompatibleMags append (compatibleMagazines [_x, _muzzles param [1, ""]]); + _compatibleMagsAll insert [true, compatibleMagazines _x, []]; } forEach [GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON, GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON, GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON, GVAR(currentItems) select IDX_CURR_BINO]; }; }; @@ -207,16 +199,18 @@ switch (_ctrlIDC) do { if (_leftPanelState) then { { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((keys ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)) arrayIntersect _compatibleItems); + if (_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)) then { + ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); + }; + } forEach _compatibleItems; } else { { - ["CfgWeapons", _x, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index); + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)); { - ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; - } forEach ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get _index); + ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; + } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get _index)); }; }; // Current primary & secondary muzzle compatible magazines @@ -224,59 +218,65 @@ switch (_ctrlIDC) do { case IDC_buttonCurrentMag2: { if (_leftPanelState) then { { - ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach ((keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) arrayIntersect _compatibleMagsMuzzle); + if (_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { + ["CfgMagazines", _x, _ctrlPanel] call FUNC(addListBoxItem); + }; + } forEach _compatibleMagsMuzzle; }; }; // All compatible magazines case IDC_buttonMag: { { - ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach ((keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) arrayIntersect _allCompatibleMags); + if (_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { + ["CfgMagazines", _x, false] call _fnc_fillRightContainer; - { - ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach ((keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)) arrayIntersect _allCompatibleMags); + continue; + }; + + if (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)) then { + ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + }; + } forEach (keys _compatibleMagsAll); }; // All magazines case IDC_buttonMagALL: { { - ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL); + ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); { - ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL); + ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)); }; // Grenades case IDC_buttonThrow: { { - ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) get IDX_VIRT_GRENADES); + ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_GRENADES)); { - ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES); + ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES)); }; // Explosives case IDC_buttonPut: { { - ["CfgMagazines", _x, false] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES); + ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)); { - ["CfgMagazines", _x, false, true] call _fnc_fill_right_Container; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES); + ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES)); }; // Misc. items case IDC_buttonMisc: { // Don't add items that will be in a custom right panel button - private _items = []; + private _items = createHashMap; if (!isNil QGVAR(customRightPanelButtons)) then { { if (!isNil "_x") then { - _items append (_x select 0); + _items insert [true, _x select 0, []]; }; } forEach GVAR(customRightPanelButtons); }; @@ -284,69 +284,64 @@ switch (_ctrlIDC) do { // "Regular" misc. items { if !(_x in _items) then { - ["CfgWeapons", _x, true] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; }; - } forEach (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)); // Unique items { if !(_x in _items) then { - ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS)); // Unique backpacks { if !(_x in _items) then { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; + ["CfgVehicles", _x, false, true] call _fnc_fillRightContainer; }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS)); // Unique goggles { if !(_x in _items) then { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; + ["CfgGlasses", _x, false, true] call _fnc_fillRightContainer; }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES)); // Unknown items { if !(_x in _items) then { - ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; + ["CfgWeapons", _x, true, true, true] call _fnc_fillRightContainer; }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS); + } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS)); }; // Custom buttons default { private _items = (GVAR(customRightPanelButtons) param [[RIGHT_PANEL_CUSTOM_BUTTONS] find _ctrlIDC, []]) param [0, []]; if (_items isNotEqualTo []) then { - // "Regular" misc. items - { - if (_x in _items) then { - ["CfgWeapons", _x, true] call _fnc_fill_right_Container; - }; - } forEach (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS); - // Unique items - { - if (_x in _items) then { - ["CfgWeapons", _x, true, true] call _fnc_fill_right_Container; - }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS); - // Unique backpacks { - if (_x in _items) then { - ["CfgVehicles", _x, false, true] call _fnc_fill_right_Container; - }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS); - // Unique goggles - { - if (_x in _items) then { - ["CfgGlasses", _x, false, true] call _fnc_fill_right_Container; - }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES); - // Unknown items - { - if (_x in _items) then { - ["CfgWeapons", _x, true, true, true] call _fnc_fill_right_Container; + + switch (true) do { + // "Regular" misc. items + case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + }; + // Unique items + case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; + }; + // Unique backpacks + case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + ["CfgVehicles", _x, false, true] call _fnc_fillRightContainer; + }; + // Unique goggles + case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + ["CfgGlasses", _x, false, true] call _fnc_fillRightContainer; + }; + // Unknown items + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS)): { + ["CfgWeapons", _x, true, true, true] call _fnc_fillRightContainer; + }; }; - } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS); + } forEach _items; }; }; }; diff --git a/addons/arsenal/functions/fnc_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index bc96631d6d6..125cb0aa867 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -29,11 +29,30 @@ switch (_currentItemsIndex) do { case IDX_CURR_PRIMARY_WEAPON_ITEMS: { // If removal if (_item == "") then { - GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex); + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removePrimaryWeaponItem _secondaryMagazine; + GVAR(center) removePrimaryWeaponItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removePrimaryWeaponItem ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex); + }; } else { // Don't add item if it isn't a different item than what the unit already has if (_item != ((GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS) select _itemIndex)) then { - GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = primaryWeapon GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [primaryWeapon GVAR(center), _item, true]; + }; }; }; @@ -50,20 +69,39 @@ switch (_currentItemsIndex) do { // If removal if (_item == "") then { // Don't unload magazines from diposable weapons - if (_isDisposable && {_itemIndex > 3}) exitWith { + if (_isDisposable && {_itemIndex >= 4}) exitWith { TRACE_1("Ignoring unload of magazine from disposable",secondaryWeapon GVAR(center)); }; - GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex); + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removeSecondaryWeaponItem _secondaryMagazine; + GVAR(center) removeSecondaryWeaponItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removeSecondaryWeaponItem ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex); + }; } else { // Don't add item if it isn't a different item than what the unit already has if (_item != ((GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex)) then { - GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = secondaryWeapon GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [secondaryWeapon GVAR(center), _item, true]; + }; }; }; // Update currentItems - if !(_isDisposable && {_itemIndex > 3}) then { + if !(_isDisposable && {_itemIndex >= 4}) then { (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; }; @@ -73,34 +111,88 @@ switch (_currentItemsIndex) do { // Handgun weapon case IDX_CURR_HANDGUN_WEAPON_ITEMS: { if (_item == "") then { - GVAR(center) removeHandgunItem ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex); + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removeHandgunItem _secondaryMagazine; + GVAR(center) removeHandgunItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removeHandgunItem ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex); + }; } else { // Don't add item if it isn't a different item than what the unit already has if (_item != ((GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS) select _itemIndex)) then { - GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = handgunWeapon GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [handgunWeapon GVAR(center), _item, true]; + }; }; }; // Update currentItems (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + // https://feedback.bistudio.com/T173880 + _primaryMagazine = _primaryMagazine param [0, ""]; + private _handgunMagazines = handgunMagazine GVAR(center); + + // Delete the first magazine (but keep one if both magazines are the same) + _handgunMagazines deleteAt (_handgunMagazines findIf {_x == _primaryMagazine}); + + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _handgunMagazines param [0, ""]]]; [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); }; // Binoculars case IDX_CURR_BINO_ITEMS: { if (_item == "") then { - GVAR(center) removeBinocularItem ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex); + private _secondaryMagazine = (GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select 5; + + // If secondary magazine, make sure to remove from correct muzzle + if (_itemIndex == 5 && {_secondaryMagazine != ""} && {((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select 4) == _secondaryMagazine}) then { + // Remove both magazines + GVAR(center) removeBinocularItem _secondaryMagazine; + GVAR(center) removeBinocularItem _secondaryMagazine; + + // Add magazine back into primary muzzle + GVAR(center) addWeaponItem [binocular GVAR(center), _secondaryMagazine, true]; + } else { + GVAR(center) removeBinocularItem ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex); + }; } else { // Don't add item if it isn't a different item than what the unit already has if (_item != ((GVAR(currentItems) select IDX_CURR_BINO_ITEMS) select _itemIndex)) then { - GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; + // If magazine, make sure to add to correct muzzle + if (_itemIndex >= 4) then { + private _weapon = binocular GVAR(center); + + GVAR(center) addWeaponItem [_weapon, [_item, nil, (_weapon call CBA_fnc_getMuzzles) param [_itemIndex - 4, ""]], true]; + } else { + GVAR(center) addWeaponItem [binocular GVAR(center), _item, true]; + }; }; }; // Update currentItems (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + + // https://feedback.bistudio.com/T173880 (unsure if binocular weapons are affected by this) + _primaryMagazine = _primaryMagazine param [0, ""]; + private _binocularMagazines = binocularMagazine GVAR(center); + + // Delete the first magazine (but keep one if both magazines are the same) + _binocularMagazines deleteAt (_binocularMagazines findIf {_x == _primaryMagazine}); + + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _binocularMagazines param [0, ""]]]; [_display, _control, _curSel, configFile >> ["CfgWeapons", "CfgMagazines"] select (_itemIndex >= 4) >> _item] call FUNC(itemInfo); }; diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index b980d50d63b..80afc46a7b4 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -33,8 +33,8 @@ private _filterFunction = toString { private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; private _className = ""; -private _configItemInfo = ""; private _simulationType = ""; +private _configItemInfo = ""; private _hasItemInfo = false; private _itemInfoType = 0; private _isMiscItem = false; @@ -124,10 +124,10 @@ private _isMiscItem = false; // Misc. items case ( _hasItemInfo && - {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD] && - {_isMiscItem}} || + {_isMiscItem && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]}} || {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || - {getText (_x >> "simulation") == "ItemMineDetector"} + {_simulationType == "ItemMineDetector"} ): { (_configItems get IDX_VIRT_MISC_ITEMS) set [_className, nil]; }; @@ -135,26 +135,22 @@ private _isMiscItem = false; } forEach configProperties [_cfgWeapons, _filterFunction, true]; // Get all grenades -private _grenadeList = []; +private _grenadeList = createHashMap; { - _grenadeList append getArray (_cfgWeapons >> "Throw" >> _x >> "magazines"); + _grenadeList insert [true, (getArray (_cfgWeapons >> "Throw" >> _x >> "magazines")) apply {_x call EFUNC(common,getConfigName)}, []]; } forEach getArray (_cfgWeapons >> "Throw" >> "muzzles"); // Get all explosives, mines, IEDS and similar -private _putList = []; +private _putList = createHashMap; { - _putList append getArray (_cfgWeapons >> "Put" >> _x >> "magazines"); + _putList insert [true, (getArray (_cfgWeapons >> "Put" >> _x >> "magazines")) apply {_x call EFUNC(common,getConfigName)}, []]; } forEach getArray (_cfgWeapons >> "Put" >> "muzzles"); -// Convert both lists to config case -_grenadeList = _grenadeList apply {_x call EFUNC(common,getConfigName)}; -_putList = _putList apply {_x call EFUNC(common,getConfigName)}; - // Remove invalid/non-existent entries -_grenadeList = _grenadeList - [""]; -_putList = _putList - [""]; +_grenadeList deleteAt ""; +_putList deleteAt ""; private _magazineMiscItems = createHashMap; @@ -223,9 +219,11 @@ private _faceCategory = ""; // Get all voices private _voiceCache = (configProperties [configFile >> "CfgVoice", "isClass _x && {getNumber (_x >> 'scope') == 2}", true]) - [configfile >> "CfgVoice" >> "NoVoice"]; +_voiceCache = _voiceCache apply {configName _x}; // Get all insignia private _insigniaCache = "(if (isNumber (_x >> 'scope')) then {getNumber (_x >> 'scope')} else {2}) == 2" configClasses (configFile >> "CfgUnitInsignia"); +_insigniaCache = _insigniaCache apply {configName _x}; // Get all disposable launchers private _launchersConfig = configProperties [configFile >> "CBA_DisposableLaunchers"]; @@ -264,5 +262,7 @@ uiNamespace setVariable [QGVAR(configItemsFlat), _configItemsFlat]; uiNamespace setVariable [QGVAR(faceCache), _faceCache]; uiNamespace setVariable [QGVAR(voiceCache), _voiceCache]; uiNamespace setVariable [QGVAR(insigniaCache), _insigniaCache]; -uiNamespace setVariable [QGVAR(CBAdisposableLaunchers), _launchers]; +uiNamespace setVariable [QGVAR(grenadeCache), _grenadeList]; +uiNamespace setVariable [QGVAR(putCache), _putList]; uiNamespace setVariable [QGVAR(magazineMiscItems), _magazineMiscItems]; +uiNamespace setVariable [QGVAR(CBAdisposableLaunchers), _launchers]; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 8f45980fa8b..c49837c5a13 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -24,8 +24,6 @@ GVAR(virtualItems) set [IDX_VIRT_UNIQUE_GOGGLES, createHashMap]; GVAR(virtualItems) set [IDX_VIRT_UNIQUE_UNKNOWN_ITEMS, createHashMap]; private _configItems = uiNamespace getVariable QGVAR(configItems); -private _configItemsFlat = uiNamespace getVariable QGVAR(configItemsFlat); -private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; @@ -34,87 +32,133 @@ private _cfgGlasses = configFile >> "CfgGlasses"; private _isMagazine = false; private _isWeapon = false; +private _config = configNull; +private _simulationType = ""; +private _configItemInfo = ""; +private _hasItemInfo = false; +private _itemInfoType = 0; +private _isMiscItem = false; { _isMagazine = isClass (_cfgMagazines >> _x); _isWeapon = isClass (_cfgWeapons >> _x); switch (true) do { - // Primary, Handgun, Secondary weapon magazines - case ( - _isMagazine && - {!(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL))} && - {_x in (_configItems get IDX_VIRT_ITEMS_ALL)} - ): { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) set [_x, nil]; - }; - // Grenades - case ( - _isMagazine && - {!(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES))} && - {_x in (_configItems get IDX_VIRT_GRENADES)} - ): { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES) set [_x, nil]; - }; - // Explosives - case ( - _isMagazine && - {!(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES))} && - {_x in (_configItems get IDX_VIRT_EXPLOSIVES)} - ): { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES) set [_x, nil]; - }; - // Optics - case ( - _isWeapon && - {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS))} && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)} - ): { - ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x, nil]; - }; - // Flashlights - case ( - _isWeapon && - {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} - ): { - ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x, nil]; - }; - // Muzzle attachments - case ( - _isWeapon && - {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS))} && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)} - ): { - ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x, nil]; - }; - // Bipods - case ( - _isWeapon && - {!(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS))} && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)} - ): { - ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x, nil]; - }; - // Misc. items - case ( - _isWeapon && - {!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS))} && - {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS))} && - {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && - {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS))} && - {!(_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS))} - ): { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; + // Magazines + case (_isMagazine): { + _config = _cfgMagazines >> _x; + + switch (true) do { + // "Misc. items" magazines (e.g. spare barrels, intel, photos) + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && + {_x in (uiNamespace getVariable QGVAR(magazineMiscItems)) || + {getNumber (_config >> "ACE_isUnique") == 1}} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; + }; + // Primary, Handgun, Secondary weapon magazines + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) && + {_x in (_configItems get IDX_VIRT_ITEMS_ALL) || + {getNumber (_config >> QGVAR(hide)) == -1} || + {getNumber (_config >> "type") in [TYPE_MAGAZINE_PRIMARY_AND_THROW, TYPE_MAGAZINE_SECONDARY_AND_PUT, 1536, TYPE_MAGAZINE_HANDGUN_AND_GL, TYPE_MAGAZINE_MISSILE]}} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL) set [_x, nil]; + }; + // Grenades + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES)) && + {_x in (uiNamespace getVariable QGVAR(grenadeCache))} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES) set [_x, nil]; + }; + // Explosives + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)) && + {_x in (uiNamespace getVariable QGVAR(putCache))} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES) set [_x, nil]; + }; + // Unknown + default { + // Don't add items that are part of the arsenal + if !(_x in GVAR(virtualItemsFlatAll)) then { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil]; + }; + }; + }; }; - // "Misc. items" magazines (e.g. spare barrels, intel, photos) - case ( - _isMagazine && - {_x in _magazineMiscItems} && - {!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS))} && - {_x in (_configItems get IDX_VIRT_MISC_ITEMS)} - ): { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; + // Weapons + case (_isWeapon): { + _config = _cfgWeapons >> _x; + _simulationType = getText (_config >> "simulation"); + _configItemInfo = _config >> "ItemInfo"; + _hasItemInfo = isClass (_configItemInfo); + _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; + _isMiscItem = _className isKindOf ["CBA_MiscItem", _cfgWeapons]; + + switch (true) do { + // Optics + case ( + !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)) && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_OPTICS}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) set [_x, nil]; + }; + // Flashlights + case ( + !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)) && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_FLASHLIGHT}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) set [_x, nil]; + }; + // Muzzle attachments + case ( + !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)) && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_MUZZLE}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) set [_x, nil]; + }; + // Bipods + case ( + !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)) && + {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) || + {_hasItemInfo && + {!_isMiscItem} && + {_itemInfoType == TYPE_BIPOD}}} + ): { + ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) set [_x, nil]; + }; + // Misc. items + case ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && + {_x in (_configItems get IDX_VIRT_MISC_ITEMS) || + {_hasItemInfo && + {_isMiscItem && + {_itemInfoType in [TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_MUZZLE, TYPE_BIPOD]}} || + {_itemInfoType in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || + {_simulationType == "ItemMineDetector"}}} + ): { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil]; + }; + // Unknown + default { + // Don't add items that are part of the arsenal + if !(_x in GVAR(virtualItemsFlatAll)) then { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil]; + }; + }; + }; }; // Backpacks case (getNumber (_cfgVehicles >> _x >> "isBackpack") == 1): { From 1b189e1fbf00894020fa62896e1bde23b291d6c3 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 14 Jul 2023 18:30:44 +0200 Subject: [PATCH 19/24] Update fnc_fillRightPanel.sqf --- addons/arsenal/functions/fnc_fillRightPanel.sqf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index c1ca01bd13f..12c7d9d32b2 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -325,15 +325,15 @@ switch (_ctrlIDC) do { ["CfgWeapons", _x, true] call _fnc_fillRightContainer; }; // Unique items - case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS)): { ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; }; // Unique backpacks - case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS)): { ["CfgVehicles", _x, false, true] call _fnc_fillRightContainer; }; // Unique goggles - case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { + case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES)): { ["CfgGlasses", _x, false, true] call _fnc_fillRightContainer; }; // Unknown items From 3507da088bbcb558fb42e7e591970591f82a3f7a Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 15 Jul 2023 09:23:23 +0200 Subject: [PATCH 20/24] Update fnc_onSelChangedLeft.sqf Fixed: Switching between weapons with incompatible primary magazines while a compatible secondary magazine is loaded doesn't equip the new weapon's primary magazine. --- .../functions/fnc_onSelChangedLeft.sqf | 114 ++++++++++++------ 1 file changed, 75 insertions(+), 39 deletions(-) diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 875aa4e94a4..e8c74025e82 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -26,11 +26,11 @@ private _item = [_control lbData _curSel, _control lnbData [_curSel, 0]] select private _selectCorrectPanelWeapon = [_display displayCtrl IDC_buttonOptic, _display displayCtrl GVAR(currentRightPanel)] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ACC_IDCS, IDC_buttonCurrentMag, IDC_buttonCurrentMag2]}); private _selectCorrectPanelContainer = [_display displayCtrl IDC_buttonMisc, _display displayCtrl GVAR(currentRightPanel)] select (!isNil QGVAR(currentRightPanel) && {GVAR(currentRightPanel) in [RIGHT_PANEL_ITEMS_IDCS]}); -// Remove all magazines from the previous weapon that aren't compatible with the new weapon -private _fnc_clearPreviousWepMags = { +// Remove all magazines from the current weapon that aren't compatible with the new weapon +private _fnc_clearCurrentWeaponMags = { private _compatibleMagsCurrentWeapon = compatibleMagazines _currentWeapon; - // If nothing was selected, remove all magazines from the previous weapon + // If nothing was selected, remove all magazines from the current weapon if (_item != "") then { _compatibleMagsCurrentWeapon = _compatibleMagsCurrentWeapon - _compatibleMags; }; @@ -55,7 +55,7 @@ switch (GVAR(currentLeftPanel)) do { // If nothing selected, remove primary weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (primaryWeapon GVAR(center)); GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, ["", "", "", "", "", ""]]; @@ -67,10 +67,9 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); - // Remove all magazines from the previous weapon that aren't compatible with the new one - call _fnc_clearPreviousWepMags; + // Remove all magazines from the current weapon that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; // Add new weapon without taking a magazine from the inventory [GVAR(center), _item] call EFUNC(common,addWeapon); @@ -93,14 +92,24 @@ switch (GVAR(currentLeftPanel)) do { }; } forEach (GVAR(currentItems) select IDX_CURR_PRIMARY_WEAPON_ITEMS); - // Add a magazine to the weapon itself if necessary - if ((primaryWeaponMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { - GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + (getUnitLoadout GVAR(center) select IDX_LOADOUT_PRIMARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; }; // Update currentItems - (getUnitLoadout GVAR(center) select IDX_LOADOUT_PRIMARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; GVAR(currentItems) set [IDX_CURR_PRIMARY_WEAPON, _item]; }; @@ -121,7 +130,7 @@ switch (GVAR(currentLeftPanel)) do { // If nothing selected, remove handgun weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (handgunWeapon GVAR(center)); GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, ["", "", "", "", "", ""]]; @@ -133,10 +142,9 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); - // Remove all magazines from the previous weapon that aren't compatible with the new one - call _fnc_clearPreviousWepMags; + // Remove all magazines from the current weapon that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; // Add new weapon without taking a magazine from the inventory [GVAR(center), _item] call EFUNC(common,addWeapon); @@ -160,14 +168,24 @@ switch (GVAR(currentLeftPanel)) do { }; } forEach (GVAR(currentItems) select IDX_CURR_HANDGUN_WEAPON_ITEMS); - // Add a magazine to the weapon itself if necessary - if ((handgunMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { - GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; }; // Update currentItems - (getUnitLoadout GVAR(center) select IDX_LOADOUT_HANDGUN_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; GVAR(currentItems) set [IDX_CURR_HANDGUN_WEAPON, _item]; }; @@ -189,7 +207,7 @@ switch (GVAR(currentLeftPanel)) do { // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (secondaryWeapon GVAR(center)); GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, ["", "", "", "", "", ""]]; @@ -201,10 +219,9 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new weapon private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); - // Remove all magazines from the previous weapon that aren't compatible with the new one - call _fnc_clearPreviousWepMags; + // Remove all magazines from the current weapon that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; // Add new weapon without taking a magazine from the inventory [GVAR(center), _item] call EFUNC(common,addWeapon); @@ -227,14 +244,24 @@ switch (GVAR(currentLeftPanel)) do { }; } forEach (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS); - // Add a magazine to the weapon itself if necessary - if ((secondaryWeaponMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { - GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; }; // Update currentItems - (getUnitLoadout GVAR(center) select IDX_LOADOUT_SECONDARY_WEAPON) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; GVAR(currentItems) set [IDX_CURR_SECONDARY_WEAPON, _item]; }; @@ -451,7 +478,7 @@ switch (GVAR(currentLeftPanel)) do { // If nothing selected, remove secondary weapon and its magazines if (_item == "") then { - call _fnc_clearPreviousWepMags; + call _fnc_clearCurrentWeaponMags; GVAR(center) removeWeapon (binocular GVAR(center)); GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, ["", "", "", "", "", ""]]; @@ -463,10 +490,9 @@ switch (GVAR(currentLeftPanel)) do { if (_item != _currentWeapon) then { // Get magazines that are compatible with the new binocular private _compatibleMags = compatibleMagazines _item; - private _compatibleMagIndex = _compatibleMags findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); - // Remove all magazines from the previous binocular that aren't compatible with the new one - call _fnc_clearPreviousWepMags; + // Remove all magazines from the current binocular that aren't compatible with the new one + call _fnc_clearCurrentWeaponMags; // Add new weapon without taking a magazine from the inventory [GVAR(center), _item] call EFUNC(common,addWeapon); @@ -489,14 +515,24 @@ switch (GVAR(currentLeftPanel)) do { }; } forEach (GVAR(currentItems) select IDX_CURR_BINO_ITEMS); - // Add a magazine to the binocular itself if necessary - if ((binocularMagazine GVAR(center)) isEqualTo [] && {_compatibleMagIndex != -1}) then { - GVAR(center) addWeaponItem [_item, _compatibleMags select _compatibleMagIndex, true]; + (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; + + _primaryMagazine = _primaryMagazine param [0, ""]; + + // Add a magazine to the primary muzzle if empty + if (_primaryMagazine == "") then { + // Get magazines that are compatible with the new weapon's primary muzzle only + private _compatibleMagsPrimaryMuzzle = compatibleMagazines [_item, "this"]; + private _compatibleMagIndex = _compatibleMagsPrimaryMuzzle findAny (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); + + if (_compatibleMagIndex != -1) then { + _primaryMagazine = _compatibleMagsPrimaryMuzzle select _compatibleMagIndex; + GVAR(center) addWeaponItem [_item, _primaryMagazine, true]; + }; }; // Update currentItems - (getUnitLoadout GVAR(center) select IDX_LOADOUT_BINO) params ["", "_muzzle", "_flashlight", "_optics", "_primaryMagazine", "_secondaryMagazine", "_bipod"]; - GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine param [0, ""], _secondaryMagazine param [0, ""]]]; + GVAR(currentItems) set [IDX_CURR_BINO_ITEMS, [_muzzle, _flashlight, _optics, _bipod, _primaryMagazine, _secondaryMagazine param [0, ""]]]; GVAR(currentItems) set [IDX_CURR_BINO, _item]; }; From 93cba2b1ab26d747769041110824c613d753772b Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 16 Jul 2023 12:09:02 -0700 Subject: [PATCH 21/24] Update addons/common/functions/fnc_uniqueUnitItems.sqf Co-authored-by: PabstMirror --- addons/common/functions/fnc_uniqueUnitItems.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/common/functions/fnc_uniqueUnitItems.sqf b/addons/common/functions/fnc_uniqueUnitItems.sqf index 4c1532d9380..97ebd78db5a 100644 --- a/addons/common/functions/fnc_uniqueUnitItems.sqf +++ b/addons/common/functions/fnc_uniqueUnitItems.sqf @@ -10,7 +10,7 @@ * 2: Uniform items (default: 2) * 3: Vest items (default: 2) * 4: Backpack items (default: 2) - * 2: Assigned items (default: true) + * 5: Assigned items (default: true) * * Return Value: * Items From 539df03378d7cf32e5f558e800fc9a0e14fb608f Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Fri, 21 Jul 2023 00:09:55 +0300 Subject: [PATCH 22/24] undefined variable Co-authored-by: PabstMirror --- addons/arsenal/functions/fnc_updateUniqueItemsList.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index c49837c5a13..13f414fe258 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -96,7 +96,7 @@ private _isMiscItem = false; _configItemInfo = _config >> "ItemInfo"; _hasItemInfo = isClass (_configItemInfo); _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; - _isMiscItem = _className isKindOf ["CBA_MiscItem", _cfgWeapons]; + _isMiscItem = _x isKindOf ["CBA_MiscItem", _cfgWeapons]; switch (true) do { // Optics From 17450ca28048e85751ae6d9b98d969fbea665705 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Fri, 21 Jul 2023 03:43:31 +0300 Subject: [PATCH 23/24] fix undefined loadout var --- addons/arsenal/functions/fnc_fillLoadoutsList.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf index 19fbdaf757b..a3fe0f7de4b 100644 --- a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -96,10 +96,9 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { { _x params ["_playerName", "_loadoutName", "_loadoutData"]; - + private _loadoutVar = _playerName + _loadoutName; // If player who shared loadout doesn't exist anymore, unshare loadout if !(_playerName in _allPlayerNames) then { - private _loadoutVar = _playerName + _loadoutName; GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars - [_loadoutVar], true]; From fac03f0a5cb6e34029bcf6fb601cceaff9b0e4cb Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Fri, 21 Jul 2023 07:22:30 +0200 Subject: [PATCH 24/24] Update fnc_fillLoadoutsList.sqf --- addons/arsenal/functions/fnc_fillLoadoutsList.sqf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf index a3fe0f7de4b..5c0ccb6467f 100644 --- a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -93,13 +93,15 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { } forEach ([profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); } else { private _allPlayerNames = allPlayers apply {name _x}; + private _loadoutVar = ""; { _x params ["_playerName", "_loadoutName", "_loadoutData"]; - private _loadoutVar = _playerName + _loadoutName; + + _loadoutVar = _playerName + _loadoutName; + // If player who shared loadout doesn't exist anymore, unshare loadout if !(_playerName in _allPlayerNames) then { - GVAR(sharedLoadoutsNamespace) setVariable [_loadoutVar, nil, true]; GVAR(sharedLoadoutsNamespace) setVariable [QGVAR(sharedLoadoutsNamespace), _sharedLoadoutsVars - [_loadoutVar], true];