ACE3/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf
Grim 007995612d
Arsenal - Fix virtual non-weapon magazines in inventory being treated as unique (#9309)
* sigh

* add comment in scanConfig

* fix misc magazines

* improve magazine misc items check

* check player loadout first for uniqueItems
2023-08-19 22:38:06 -04:00

281 lines
12 KiB
Plaintext

#include "script_component.hpp"
#include "..\defines.hpp"
/*
* Author: Alganthe, johnb43
* 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
*
* Return Value:
* None
*
* Public: No
*/
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 _cfgWeapons = configFile >> "CfgWeapons";
private _cfgMagazines = configFile >> "CfgMagazines";
private _cfgVehicles = configFile >> "CfgVehicles";
private _cfgGlasses = configFile >> "CfgGlasses";
// 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
private _isMagazine = false;
private _isWeapon = false;
private _isGrenade = false;
private _isPut = false;
private _isMiscItem = false;
private _config = configNull;
private _simulationType = "";
private _configItemInfo = "";
private _hasItemInfo = false;
private _itemInfoType = 0;
{
_isMagazine = isClass (_cfgMagazines >> _x);
_isWeapon = isClass (_cfgWeapons >> _x);
switch (true) do {
// Magazines
case (_isMagazine): {
_config = _cfgMagazines >> _x;
_isGrenade = _x in (uiNamespace getVariable QGVAR(grenadeCache));
_isPut = _x in (uiNamespace getVariable QGVAR(putCache));
_isMiscItem = _x in (uiNamespace getVariable QGVAR(magazineMiscItems));
switch (true) do {
// "Misc. items" magazines (e.g. spare barrels, intel, photos)
case (
!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) &&
{_isMiscItem}
): {
(GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS) set [_x, nil];
};
// Grenades
case (
!(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES)) &&
{_isGrenade}
): {
(GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES) set [_x, nil];
};
// Explosives
case (
!(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)) &&
{_isPut}
): {
(GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES) set [_x, nil];
};
// Primary, Handgun, Secondary weapon magazines
case (
!(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) &&
{!_isGrenade && {!_isPut} && {!_isMiscItem}} &&
{_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];
};
// 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];
};
};
};
};
// 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 = _x 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): {
(GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS) set [_x, nil];
};
// Facewear
case (isClass (_cfgGlasses >> _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 GVAR(virtualItemsFlatAll)) then {
(GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil];
};
};
};
} forEach (keys ([GVAR(center), 0, 3, 3, 3, false] call EFUNC(common,uniqueUnitItems))); // Get all items from unit