From 35ce8d1883d701bbee561a3ead92a69d15b724bf Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Sat, 22 Jul 2023 06:31:30 +0300 Subject: [PATCH] Common - Add variable to block item replacement temporarily (#9265) * add blocking item replacement * don't add if player changed * re-curse instead of fake item * compileFinal * Update fnc_registerItemReplacement.sqf * move to separate function * remove fakeitem replacement --------- Co-authored-by: PabstMirror --- addons/arsenal/XEH_preInit.sqf | 2 + addons/common/CfgWeapons.hpp | 1 - addons/common/XEH_PREP.hpp | 1 + addons/common/XEH_preInit.sqf | 2 + .../functions/fnc_registerItemReplacement.sqf | 69 +-------------- .../functions/fnc_replaceRegisteredItems.sqf | 83 +++++++++++++++++++ 6 files changed, 91 insertions(+), 67 deletions(-) create mode 100644 addons/common/functions/fnc_replaceRegisteredItems.sqf diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 08457b5237..711da4a037 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -58,11 +58,13 @@ call FUNC(compileSorts); [QGVAR(displayOpened), { "CBA_optics_arsenalOpened" call CBA_fnc_localEvent; "CBA_disposable_arsenalOpened" call CBA_fnc_localEvent; + EGVAR(common,blockItemReplacement) = true; }] call CBA_fnc_addEventHandler; [QGVAR(displayClosed), { "CBA_optics_arsenalClosed" call CBA_fnc_localEvent; "CBA_disposable_arsenalClosed" call CBA_fnc_localEvent; + EGVAR(common,blockItemReplacement) = false; }] call CBA_fnc_addEventHandler; // Setup Tools tab diff --git a/addons/common/CfgWeapons.hpp b/addons/common/CfgWeapons.hpp index 09a828e475..8662df8d82 100644 --- a/addons/common/CfgWeapons.hpp +++ b/addons/common/CfgWeapons.hpp @@ -39,4 +39,3 @@ class CfgWeapons { }; }; }; - diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 7646b4d73d..d016ab26d6 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -145,6 +145,7 @@ PREP(receiveRequest); PREP(registerItemReplacement); PREP(removeCanInteractWithCondition); PREP(removeSpecificMagazine); +PREP(replaceRegisteredItems); PREP(requestCallback); PREP(resetAllDefaults); PREP(restoreVariablesJIP); diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 8daee5c64c..95f61fa7a1 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -11,6 +11,8 @@ GVAR(syncedEvents) = createHashMap; GVAR(showHudHash) = createHashMap; GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon +GVAR(blockItemReplacement) = false; + // Cache for FUNC(isModLoaded) GVAR(isModLoadedCache) = createHashMap; diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf index 4f8429678c..bd078800f6 100644 --- a/addons/common/functions/fnc_registerItemReplacement.sqf +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -20,76 +20,13 @@ params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]]; TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited); -// CBA player event handler function -private _fnc_replaceItems = { - params ["_unit"]; - - private _items = items _unit; - if (_items isEqualTo GVAR(oldItems)) exitWith {}; - - private _newItems = _items - GVAR(oldItems); - _newItems = _newItems arrayIntersect _newItems; // Get unique items only - if (_newItems isEqualTo []) exitWith { - GVAR(oldItems) = _items; - }; - - private _cfgWeapons = configFile >> "CfgWeapons"; // Microoptimization - - for "_i" from 0 to count _newItems - 1 do { - private _item = _newItems#_i; - - // Get count of item in each container - private _containerCount = []; - { - _containerCount pushBack ({_x == _item} count _x) - } forEach [uniformItems _unit, vestItems _unit, backpackItems _unit]; - - // Determine replacement items: direct replacements, ... - private _replacements = GVAR(itemReplacements) getVariable [_item, []]; - - // ... item type replacements ... - private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); - private _typeReplacements = GVAR(itemReplacements) getVariable ["$" + str _type, []]; - _replacements append _typeReplacements; - - // ... and inherited replacements - { - if (_item isKindOf [_x, _cfgWeapons]) then { - private _inheritedReplacements = GVAR(itemReplacements) getVariable [_x, []]; - _replacements append _inheritedReplacements; - }; - } forEach GVAR(inheritedReplacements); - - // Replace all items of current class in list - if (_replacements isNotEqualTo []) then { - TRACE_3("replace",_item,_count,_replacements); - _unit removeItems _item; - - { - if (_x == 0) then {continue}; - private _container = ["uniform", "vest", "backpack"] select _forEachIndex; - for "_j" from 1 to _x do { - { - if ([_unit, _x, 1, _container == "uniform", _container == "vest", _container == "backpack"] call CBA_fnc_canAddItem) then { - [_unit, _x, _container] call FUNC(addToInventory) // add to specific container - } else { - [_unit, _x, ""] call FUNC(addToInventory) // no room, add anywhere - } - } forEach _replacements; - } - } forEach _containerCount; - }; - }; - - GVAR(oldItems) = items _unit; -}; // Setup on first run if (isNil QGVAR(itemReplacements)) then { GVAR(itemReplacements) = [] call CBA_fnc_createNamespace; GVAR(inheritedReplacements) = []; GVAR(oldItems) = []; - ["loadout", _fnc_replaceItems] call CBA_fnc_addPlayerEventHandler; + ["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler; }; // Save item replacement @@ -110,12 +47,12 @@ _oldReplacements append _newItems; GVAR(itemReplacements) setVariable [_oldItem, _oldReplacements]; // Force item scan when new replacement was registered in PostInit -if (!isNull ACE_player) then { +if !(isNull ACE_player) then { GVAR(oldItems) = []; // Exec next frame to ensure full scan only runs once per frame // For example, if item replacements are registred in PostInit (due to CBA // settings) by different addons, the inventory is only scanned once in the // next frame, not once per addon. - [_fnc_replaceItems, [ACE_player]] call CBA_fnc_execNextFrame; + [LINKFUNC(replaceRegisteredItems), [ACE_player]] call CBA_fnc_execNextFrame; }; diff --git a/addons/common/functions/fnc_replaceRegisteredItems.sqf b/addons/common/functions/fnc_replaceRegisteredItems.sqf new file mode 100644 index 0000000000..8ebdaeecec --- /dev/null +++ b/addons/common/functions/fnc_replaceRegisteredItems.sqf @@ -0,0 +1,83 @@ +#include "script_component.hpp" +/* + * Author: BaerMitUmlaut + * Handles replacing unit's items with their registered replacements. + * Called by CBA Player Loadout Event, but can be used to replace items on AI. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [ACE_player] call ace_common_fnc_replaceRegisteredItems + * + * Public: Yes + */ +params [["_unit", objNull, [objNull]]]; + +private _items = items _unit; +if (_items isEqualTo GVAR(oldItems)) exitWith {}; + +private _newItems = _items - GVAR(oldItems); +_newItems = _newItems arrayIntersect _newItems; // Get unique items only +if (_newItems isEqualTo []) exitWith { + GVAR(oldItems) = _items; +}; +TRACE_2("replacing",_unit,_newItems); + +if (GVAR(blockItemReplacement)) exitWith { + TRACE_2("blocked delay",_unit,_newItems); + [{!GVAR(blockItemReplacement)}, LINKFUNC(replaceRegisteredItems), _unit] call CBA_fnc_waitUntilAndExecute; +}; + +private _cfgWeapons = configFile >> "CfgWeapons"; // Microoptimization + +for "_i" from 0 to count _newItems - 1 do { + private _item = _newItems#_i; + + // Get count of item in each container + private _containerCount = []; + { + _containerCount pushBack ({_x == _item} count _x) + } forEach [uniformItems _unit, vestItems _unit, backpackItems _unit]; + + // Determine replacement items: direct replacements, ... + private _replacements = GVAR(itemReplacements) getVariable [_item, []]; + + // ... item type replacements ... + private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); + private _typeReplacements = GVAR(itemReplacements) getVariable ["$" + str _type, []]; + _replacements append _typeReplacements; + + // ... and inherited replacements + { + if (_item isKindOf [_x, _cfgWeapons]) then { + private _inheritedReplacements = GVAR(itemReplacements) getVariable [_x, []]; + _replacements append _inheritedReplacements; + }; + } forEach GVAR(inheritedReplacements); + + // Replace all items of current class in list + if (_replacements isNotEqualTo []) then { + TRACE_3("replace",_item,_count,_replacements); + _unit removeItems _item; + + { + if (_x == 0) then {continue}; + private _container = ["uniform", "vest", "backpack"] select _forEachIndex; + for "_j" from 1 to _x do { + { + if ([_unit, _x, 1, _container == "uniform", _container == "vest", _container == "backpack"] call CBA_fnc_canAddItem) then { + [_unit, _x, _container] call FUNC(addToInventory) // add to specific container + } else { + [_unit, _x, ""] call FUNC(addToInventory) // no room, add anywhere + } + } forEach _replacements; + } + } forEach _containerCount; + }; +}; + +GVAR(oldItems) = items _unit;