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 <pabstmirror@gmail.com>
This commit is contained in:
Grim 2023-07-22 06:31:30 +03:00 committed by GitHub
parent e5dc124fe8
commit 35ce8d1883
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 91 additions and 67 deletions

View File

@ -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

View File

@ -39,4 +39,3 @@ class CfgWeapons {
};
};
};

View File

@ -145,6 +145,7 @@ PREP(receiveRequest);
PREP(registerItemReplacement);
PREP(removeCanInteractWithCondition);
PREP(removeSpecificMagazine);
PREP(replaceRegisteredItems);
PREP(requestCallback);
PREP(resetAllDefaults);
PREP(restoreVariablesJIP);

View File

@ -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;

View File

@ -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;
};

View File

@ -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 <OBJECT>
*
* 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;