From 174841751cd33c18cbc868622b92213d2878ea31 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 25 Jul 2023 08:41:15 +0200 Subject: [PATCH] Arsenal - Improve support for unique equipment (#9287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * work on arsenal actions * cycle through pages * docs * cleanup * Update addons/gunbag/functions/fnc_weaponName.sqf Co-authored-by: Jouni Järvinen * missing fil * Update addons/arsenal/functions/fnc_itemInfo.sqf * Update addons/arsenal/functions/fnc_refresh.sqf Co-authored-by: Jouni Järvinen * remove CBA_loadoutSet gunbag cache * update fnc_refresh * Added unique item support for left panel items * Cleanup * fix 3den * add scopeEditor --------- Co-authored-by: Brett Co-authored-by: Jouni Järvinen Co-authored-by: Salluci Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/arsenal/functions/fnc_buttonImport.sqf | 7 +- .../functions/fnc_buttonLoadoutsLoad.sqf | 7 +- .../arsenal/functions/fnc_compileActions.sqf | 3 + addons/arsenal/functions/fnc_itemInfo.sqf | 12 +-- .../arsenal/functions/fnc_onArsenalOpen.sqf | 95 +----------------- addons/arsenal/functions/fnc_refresh.sqf | 13 ++- .../functions/fnc_updateUniqueItemsList.sqf | 99 ++++++++++++++++++- addons/gunbag/ACE_Arsenal_Actions.hpp | 1 + docs/wiki/framework/arsenal-framework.md | 1 + 9 files changed, 124 insertions(+), 114 deletions(-) diff --git a/addons/arsenal/functions/fnc_buttonImport.sqf b/addons/arsenal/functions/fnc_buttonImport.sqf index eea1370f9b..ac4f947cfa 100644 --- a/addons/arsenal/functions/fnc_buttonImport.sqf +++ b/addons/arsenal/functions/fnc_buttonImport.sqf @@ -50,11 +50,8 @@ if (GVAR(shiftState) && {is3DEN}) then { if ((count _extendedLoadout) == 2) then { [GVAR(center), _extendedLoadout] call CBA_fnc_setLoadout; - // 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); + // Update current item list and unique items + call FUNC(refresh); _extendedLoadout params ["_loadout", "_extendedInfo"]; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf index 9b09c0d66c..99f7894311 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsLoad.sqf @@ -37,11 +37,8 @@ private _extendedLoadout = switch (GVAR(currentLoadoutsTab)) do { // Apply loadout to unit [GVAR(center), _extendedLoadout, true] call CBA_fnc_setLoadout; -// 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); +// Update current item list and unique items +call FUNC(refresh); _extendedLoadout params ["_loadout", "_extendedInfo"]; diff --git a/addons/arsenal/functions/fnc_compileActions.sqf b/addons/arsenal/functions/fnc_compileActions.sqf index 921f7342e6..2bf4fe51b0 100644 --- a/addons/arsenal/functions/fnc_compileActions.sqf +++ b/addons/arsenal/functions/fnc_compileActions.sqf @@ -38,6 +38,9 @@ private _actionList = [ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)); { + private _scopeEditor = getNumber (_x >> "scopeEditor"); + if (is3DEN && {_scopeEditor != 2}) then {continue}; + private _configActions = "true" configClasses _x; private _rootDisplayName = getText (_x >> "displayName"); diff --git a/addons/arsenal/functions/fnc_itemInfo.sqf b/addons/arsenal/functions/fnc_itemInfo.sqf index 9dad0c0247..793d5a85e2 100644 --- a/addons/arsenal/functions/fnc_itemInfo.sqf +++ b/addons/arsenal/functions/fnc_itemInfo.sqf @@ -49,16 +49,16 @@ if (isClass _itemCfg) then { // 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 ["MouseExit", format ["(_this select 0) ctrlSetText '%1';", _logo]]; + _ctrlDLC ctrlSetEventHandler ["MouseEnter", format ["(_this select 0) ctrlSetText '%1';", _logoOver]]; _ctrlDLC ctrlSetEventHandler [ - "buttonClick", + "ButtonClick", format ["uiNamespace setVariable ['RscDisplayDLCPreview_dlc','%1']; ctrlParent (_this select 0) createDisplay 'RscDisplayDLCPreview';", _dlc] ]; } else { - _ctrlDLC ctrlRemoveAllEventHandlers "mouseExit"; - _ctrlDLC ctrlRemoveAllEventHandlers "mouseEnter"; - _ctrlDLC ctrlRemoveAllEventHandlers "buttonClick"; + _ctrlDLC ctrlRemoveAllEventHandlers "MouseExit"; + _ctrlDLC ctrlRemoveAllEventHandlers "MouseEnter"; + _ctrlDLC ctrlRemoveAllEventHandlers "ButtonClick"; }; } else { _ctrlDLC ctrlSetFade 1; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index ce6b81a0f3..9ba2079999 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -76,6 +76,8 @@ if (isNil QGVAR(virtualItems)) then { GVAR(virtualItemsFlat) = _virtualItemsFlat; }; +GVAR(virtualItemsFlatAll) = +GVAR(virtualItemsFlat); + GVAR(currentFace) = face GVAR(center); GVAR(currentVoice) = speaker GVAR(center); GVAR(currentInsignia) = GVAR(center) call BIS_fnc_getUnitInsignia; @@ -91,101 +93,10 @@ GVAR(statsInfo) = [true, 0, controlNull, nil, nil]; GVAR(showActions) = true; GVAR(currentActionPage) = 0; -// Add the items the player has to virtualItems -{ - 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 FUNC(baseWeapon); - - // If bino, add it in a different place than regular weapons - if (_forEachIndex != IDX_LOADOUT_BINO) then { - ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _forEachIndex) set [_weapon, nil]; - } else { - (GVAR(virtualItems) get IDX_VIRT_BINO) set [_weapon, nil]; - }; - }; - - // Add weapon attachments - { - if (_x != "") then { - ((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 (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, vest, backpack - case IDX_LOADOUT_UNIFORM; - case IDX_LOADOUT_VEST; - case IDX_LOADOUT_BACKPACK: { - _x params [["_containerClass", ""]]; - - if (_containerClass != "") then { - (GVAR(virtualItems) get (_forEachIndex + 1)) set [_containerClass, nil]; - }; - }; - // Helmet - case IDX_LOADOUT_HEADGEAR: { - if (_x != "") then { - (GVAR(virtualItems) get IDX_VIRT_HEADGEAR) set [_x, nil]; - }; - }; - // Facewear - case IDX_LOADOUT_GOGGLES: { - if (_x != "") then { - (GVAR(virtualItems) get IDX_VIRT_GOGGLES) set [_x, nil]; - }; - }; - // 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) 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); -// This takes care of items that aren't available in the arsenal (either wrong tab or arsenal doesn't have it whitelisted) +// This takes care of unique inventory items and unique equipment (arsenal doesn't have items/equipment whitelisted) call FUNC(updateUniqueItemsList); [QGVAR(displayOpened), [_display]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_refresh.sqf b/addons/arsenal/functions/fnc_refresh.sqf index 8f3ebab7ae..4b22e72f04 100644 --- a/addons/arsenal/functions/fnc_refresh.sqf +++ b/addons/arsenal/functions/fnc_refresh.sqf @@ -1,8 +1,8 @@ #include "script_component.hpp" #include "..\defines.hpp" /* - * Author: Brett Mayson - * Refreshes the arsenal to show external changes + * Author: Brett Mayson, johnb43 + * Refreshes the arsenal to show external changes. * * Return Value: * None @@ -10,10 +10,15 @@ * Public: No */ -private _display = findDisplay IDD_ace_arsenal; - +// Update current item list call FUNC(updateCurrentItemsList); +// This takes care of unique inventory items (arsenal doesn't have it whitelisted) call FUNC(updateUniqueItemsList); +// Don't refresh left panel if in loadout tab +if (!isNull findDisplay IDD_loadouts_display) exitWith {}; + +private _display = findDisplay IDD_ace_arsenal; + [_display, _display displayCtrl GVAR(currentLeftPanel)] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index 13f414fe25..c7a819af85 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -2,8 +2,9 @@ #include "..\defines.hpp" /* * Author: Alganthe, johnb43 - * Updates the list of unique items. - * Unique items are items that can't be multiplied using the arsenal. + * Updates the list of unique inventory items and unique equipment. + * Unique inventory items are items within containers that can't be multiplied using the arsenal. + * Unique equipment are any items (such as weapons, containers, etc.) that can't be multiplied using the arsenal. * * Arguments: * None @@ -177,3 +178,97 @@ private _isMiscItem = false; }; }; } forEach (keys ([GVAR(center), 0, 3, 3, 3, false] call EFUNC(common,uniqueUnitItems))); // Get all items from unit + +// Remove unique equipment in every panel +private _items = createHashMap; + +private _fnc_uniqueEquipment = { + params ["_items", "_item", ["_removeAllUniqueItems", true]]; + + // Remove all unique equipment from tab + if (_removeAllUniqueItems) then { + private _itemsToDelete = []; + + { + if (!isNil "_y") then { + _itemsToDelete pushBack _x; + }; + } forEach _items; + + { + _items deleteAt _x; + GVAR(virtualItemsFlatAll) deleteAt _x; + } forEach _itemsToDelete; + }; + + // Add item as a unique equipment + if (_item != "") then { + _items set [_item, true, true]; + GVAR(virtualItemsFlatAll) set [_item, true, true]; + }; +}; + +// Add the items the player has to virtualItems as unique equipment +{ + 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", ""]]; + + // If bino, add it in a different place than regular weapons + _items = if (_forEachIndex != IDX_LOADOUT_BINO) then { + (GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _forEachIndex + } else { + GVAR(virtualItems) get IDX_VIRT_BINO + }; + + // Remove all unique equipment in tab; Add weapon as a unique equipment + [_items, _weapon call FUNC(baseWeapon)] call _fnc_uniqueEquipment; + + private _removeUniqueItems = _forEachIndex == IDX_LOADOUT_PRIMARY_WEAPON; + + // Add weapon attachments + { + // Remove all unique equipment in tab; Add weapon attachment as a unique equipment + [(GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _forEachIndex, _x call FUNC(baseWeapon), _removeUniqueItems] call _fnc_uniqueEquipment; + } forEach [_optics, _flashlight, _muzzle, _bipod]; + + // Add magazines + { + // Remove all unique equipment in tab; Add magazine as unique equipment + [GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL, _x param [0, ""], _removeUniqueItems && {_forEachIndex == 0}] call _fnc_uniqueEquipment; + } forEach [_primaryMagazine, _secondaryMagazine]; + }; + + // Uniform, vest, backpack + case IDX_LOADOUT_UNIFORM; + case IDX_LOADOUT_VEST; + case IDX_LOADOUT_BACKPACK: { + _x params [["_containerClass", ""]]; + + // Remove all unique equipment in tab; Add container as a unique equipment + [GVAR(virtualItems) get (_forEachIndex + 1), _containerClass] call _fnc_uniqueEquipment; + }; + // Helmet + case IDX_LOADOUT_HEADGEAR: { + // Remove all unique equipment in tab; Add item as a unique equipment + [GVAR(virtualItems) get IDX_VIRT_HEADGEAR, _x] call _fnc_uniqueEquipment; + }; + // Facewear + case IDX_LOADOUT_GOGGLES: { + // Remove all unique equipment in tab; Add item as a unique equipment + [GVAR(virtualItems) get IDX_VIRT_GOGGLES, _x] call _fnc_uniqueEquipment; + }; + // 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 + // Remove all unique equipment in tab; Add item as a unique equipment + [GVAR(virtualItems) get (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _forEachIndex)), _x] call _fnc_uniqueEquipment; + } forEach _x; + }; + }; +} forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout diff --git a/addons/gunbag/ACE_Arsenal_Actions.hpp b/addons/gunbag/ACE_Arsenal_Actions.hpp index b9d2e5f21f..32a16e99d3 100644 --- a/addons/gunbag/ACE_Arsenal_Actions.hpp +++ b/addons/gunbag/ACE_Arsenal_Actions.hpp @@ -2,6 +2,7 @@ class EGVAR(arsenal,actions) { class ADDON { displayName = CSTRING(DisplayName); condition = QUOTE(_this call FUNC(hasGunbag)); + scopeEditor = 0; // variables are reset between 3DEN and mission start tabs[] = {0,5}; class status { textStatement = QUOTE([_this select 0] call FUNC(weaponName)); diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index cbe43ac113..b0ee255493 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -395,6 +395,7 @@ class ace_arsenal_actions { class TAG_myActions { displayName = "My Actions"; condition = QUOTE(true); + scopeEditor = 2; // Only actions with scopeEditor = 2 are shown in 3DEN. Actions working with variables should take object variables being reset between editor view and mission start into account. tabs[] = {0,5}; class text { // A simple text label