Skip to content

Commit

Permalink
Arsenal - Improve performance of loadout verification (#9316)
Browse files Browse the repository at this point in the history
Co-authored-by: johnb432 <[email protected]>
  • Loading branch information
LinkIsGrim and johnb432 authored Feb 10, 2024
1 parent 41c7b12 commit 6928adf
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 263 deletions.
6 changes: 3 additions & 3 deletions addons/arsenal/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ GVAR(lastSortDirectionRight) = DESCENDING;
if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then {
private _curSelData = _contentPanelCtrl lnbData [lnbCurSelRow _contentPanelCtrl, 1];

([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
_extendedLoadout params ["_loadout"];

private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName];
Expand All @@ -81,10 +81,10 @@ GVAR(lastSortDirectionRight) = DESCENDING;
_contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName];

// Set color of row, depending if items are unavailable/missing
if (_nullItemsAmount > 0) then {
if (_nullItemsList isNotEqualTo []) then {
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]];
} else {
if (_unavailableItemsAmount > 0) then {
if (_unavailableItemsList isNotEqualTo []) then {
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]];
};
};
Expand Down
16 changes: 8 additions & 8 deletions addons/arsenal/functions/fnc_fillLoadoutsList.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
_loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout);
_contentPanelCtrl setVariable [_loadoutNameAndTab, _loadoutCachedInfo];

_loadoutCachedInfo params ["", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"];
_loadoutCachedInfo params ["", "_nullItemsList", "_unavailableItemsList"];

// Log missing / nil items to RPT (only once per arsenal session)
if (GVAR(EnableRPTLog) && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then {
if (GVAR(EnableRPTLog) && {(_nullItemsList isNotEqualTo []) || {_unavailableItemsList isNotEqualTo []}}) then {
private _printComponent = "ACE_Arsenal - Loadout:";
private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " ";
private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " ";
Expand All @@ -69,18 +69,18 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
_contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90];
};

_loadoutCachedInfo params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
_loadoutCachedInfo params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
_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 {
if (_nullItemsList isNotEqualTo []) then {
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red
} else {
if (_unavailableItemsAmount > 0) then {
if (_unavailableItemsList isNotEqualTo []) then {
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray
};
};
Expand All @@ -107,7 +107,7 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {

[QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent;
} else {
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"];
([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"];
_extendedLoadout params ["_loadout"];

_contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90];
Expand All @@ -118,10 +118,10 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then {
_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 {
if (_nullItemsList isNotEqualTo []) then {
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red
} else {
if (_unavailableItemsAmount > 0) then {
if (_unavailableItemsList isNotEqualTo []) then {
_contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray
};
};
Expand Down
280 changes: 28 additions & 252 deletions addons/arsenal/functions/fnc_verifyLoadout.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -23,275 +23,51 @@ if (count _loadout == 2) then {
_loadout = _loadout select 0;
};

private _cfgWeapons = configFile >> "CfgWeapons";
private _cfgMagazines = configFile >> "CfgMagazines";
private _cfgVehicles = configFile >> "CfgVehicles";
private _cfgGlasses = configFile >> "CfgGlasses";

private _weapons = GVAR(virtualItems) get IDX_VIRT_WEAPONS;
private _attachments = GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS;

private _name = "";
private _nullItemsAmount = 0;
private _unavailableItemsAmount = 0;
private _itemArray = [];
private _nullItemsList = [];
private _unavailableItemsList = [];

// Search for all items and turn them into config case; Don't touch other value types
private _fnc_toConfigCase = {
// Search for all items and check their availability
private _fnc_filterLoadout = {
_this apply {
if (_x isEqualType "") then {
if (_x != "") then {
_name = _x call EFUNC(common,getConfigName);
if (_x isEqualType "" && {_x != ""}) then {
_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
[_x, _name] select (_name != "");
// If item doesn't exist in config, "" is returned
if (_name == "") then {
_nullItemsList pushBack _x;
} else {
_x
// Check if item or its base weapon exist in the arsenal
if !(_name in GVAR(virtualItemsFlat)) then {
_name = _name call FUNC(baseWeapon);
if !(_name in GVAR(virtualItemsFlat)) then {
_unavailableItemsList pushBack _name;
_name = "";
};
};
};

_name
} else {
// Handle arrays
if (_x isEqualType []) then {
_x call _fnc_toConfigCase
_itemArray = _x call _fnc_filterLoadout;
// If "" is given as a container, an error is thrown, therefore, filter out all unavailable/null containers
if (count _itemArray == 2 && {(_itemArray select 0) isEqualTo ""} && {(_itemArray select 1) isEqualType []}) then {
_itemArray = [];
};
_itemArray
} else {
// All other types
// All other types and empty strings
_x
};
};
};
};

// Convert loadout to config case
// Convert loadout to config case and replace null/unavailable items
// Loadout might come from a different modpack, which might have different config naming
_loadout = _loadout call _fnc_toConfigCase;

// 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 {
// 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
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) get IDX_VIRT_BINO)
} else {
_x in (_weapons get _index)
};
} else {
_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 (_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;
_weaponArray set [_forEachIndex, ""];
INC(_unavailableItemsAmount);
};
} else {
_nullItemsList pushBackUnique _x;
_weaponArray set [_forEachIndex, ""];
INC(_nullItemsAmount);
};
};
} 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) get IDX_VIRT_ITEMS_ALL)) then {
_unavailableItemsList pushBackUnique _magazine;
_weaponArray set [_forEachIndex, []];
INC(_unavailableItemsAmount);
};
} else {
_nullItemsList pushBackUnique _magazine;
_weaponArray set [_forEachIndex, []];
INC(_nullItemsAmount);
};
};
};
} forEach _weaponArray;
};

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 {
// 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", []]];

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) get (_dataIndex + 1))) then {
_unavailableItemsList pushBackUnique _item;
_loadout set [_dataIndex, []];
INC(_unavailableItemsAmount);
} else {
{
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) 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, []];
INC(_unavailableItemsAmount);
};
} else {
_nullItemsList pushBackUnique _item;
((_loadout select _dataIndex) select 1) set [_forEachIndex, []];
INC(_nullItemsAmount);
};
};
// 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 !(_item in GVAR(virtualItemsFlat)) 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;
};
} else {
_nullItemsList pushBackUnique _item;
_loadout set [_dataIndex, []];
INC(_nullItemsAmount);
};
};
};
// Headgear
case IDX_LOADOUT_HEADGEAR: {
_item = _loadout select _dataIndex;

if (_item != "") then {
// Check if item exists
if (isClass (_cfgWeapons >> _item)) then {
// Check if item is available in arsenal
if !(_item in (GVAR(virtualItems) get IDX_VIRT_HEADGEAR)) then {
_unavailableItemsList pushBackUnique _item;
_loadout set [_dataIndex, ""];
INC(_unavailableItemsAmount);
};
} else {
_nullItemsList pushBackUnique _item;
_loadout set [_dataIndex, ""];
INC(_nullItemsAmount);
};
};
};
// Facewear
case IDX_LOADOUT_GOGGLES: {
_item = _loadout select _dataIndex;

if (_item != "") then {
// Check if item exists
if (isClass (_cfgGlasses >> _item)) then {
// Check if item is available in arsenal
if !(_item in (GVAR(virtualItems) get IDX_VIRT_GOGGLES)) then {
_unavailableItemsList pushBackUnique _item;
_loadout set [_dataIndex, ""];
INC(_unavailableItemsAmount);
};
} else {
_nullItemsList pushBackUnique _item;
_loadout set [_dataIndex, ""];
INC(_nullItemsAmount);
};
};
};
// Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs
case IDX_LOADOUT_ASSIGNEDITEMS: {
private _assignedItems = _loadout select _dataIndex;

for "_subIndex" from 0 to 5 do {
_item = _assignedItems select _subIndex;

if (_item != "") then {
// Check if item exists
if (isClass (_cfgWeapons >> _item)) then {
// Check if item is available in arsenal
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);
};
} else {
_nullItemsList pushBackUnique _item;
_assignedItems set [_subIndex, ""];
INC(_nullItemsAmount);
};
};
};
};
};
};
_loadout = _loadout call _fnc_filterLoadout;

[[_loadout, _extendedInfo], _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList]
[[_loadout, _extendedInfo], _nullItemsList arrayIntersect _nullItemsList, _unavailableItemsList arrayIntersect _unavailableItemsList]

0 comments on commit 6928adf

Please sign in to comment.