diff --git a/addons/common/fnc_removeBackpackCargo.sqf b/addons/common/fnc_removeBackpackCargo.sqf index fdb34f761..9c2a0d440 100644 --- a/addons/common/fnc_removeBackpackCargo.sqf +++ b/addons/common/fnc_removeBackpackCargo.sqf @@ -97,6 +97,7 @@ clearBackpackCargoGlobal _container; // Put attachments next to weapon, no command to put it directly onto a weapon when weapon is in a container { _x params ["_weapon", "_muzzle", "_pointer", "_optic", "_magazine", "_magazineGL", "_bipod"]; + // weaponsItems magazineGL does not exist if not loaded (not even as empty array) if (count _x < 7) then { _bipod = _magazineGL; diff --git a/addons/common/fnc_removeItemCargo.sqf b/addons/common/fnc_removeItemCargo.sqf index 3cc130093..5395a8914 100644 --- a/addons/common/fnc_removeItemCargo.sqf +++ b/addons/common/fnc_removeItemCargo.sqf @@ -4,6 +4,8 @@ Function: CBA_fnc_removeItemCargo Description: Removes specific item(s) from cargo space. + Warning: All weapon attachments/magazines in containers in container will become detached. + Parameters: _container - Object with cargo _item - Classname of item(s) to remove @@ -54,7 +56,18 @@ if (_count <= 0) exitWith { // Ensure proper count _count = round _count; -// Returns array containing two arrays: [[type1, typeN, ...], [count1, countN, ...]] +// Save containers and contents +private _containerData = []; // [object1, object2, ...] +private _containerNames = []; +{ + _x params ["_class", "_object"]; + if !(_object in (everyBackpack _container)) then { + _containerData pushBack [getItemCargo _object, magazinesAmmoCargo _object, weaponsItemsCargo _object]; + _containerNames pushBack _class; + }; +} forEach (everyContainer _container); // [["class1", object1], ["class2", object2]] + +// [[type1, typeN, ...], [count1, countN, ...]] (getItemCargo _container) params ["_allItemsType", "_allItemsCount"]; // Clear cargo space and readd the items as long it's not the type in question @@ -62,18 +75,75 @@ clearItemCargoGlobal _container; { private _itemCount = _allItemsCount select _forEachIndex; + private _containerIndex = _containerNames find _x; if (_count != 0 && {_x == _item}) then { // Process removal - _itemCount = _itemCount - _count; - if (_itemCount > 0) then { - // Add with new count - _container addItemCargoGlobal [_x, _itemCount]; + if (_containerIndex < 0) then { + _itemCount = _itemCount - _count; + if (_itemCount > 0) then { + // Add with new count + _container addItemCargoGlobal [_x, _itemCount]; + }; + } else { + _containerData deleteAt _containerIndex; + _containerNames deleteAt _containerIndex; }; _count = 0; } else { // Readd only - _container addItemCargoGlobal [_x, _itemCount]; + if (_containerIndex < 0) then { + _container addItemCargoGlobal [_x, _itemCount]; + } else { + (_containerData select _containerIndex) params ["_itemCargo", "_magazinesAmmoCargo", "_weaponsItemsCargo"]; + + // Save all containers for finding the one we readd after this + private _addedContainers = ((everyContainer _container) apply {_x select 1}) - everyBackpack _container; + + // Readd + private _addedContainer = [_containerNames select _containerIndex] call CBA_fnc_getNonPresetClass; + _container addItemCargoGlobal [_addedContainer, 1]; + + // Find just added container and add contents (no command returns reference when adding) + private _addedContainer = ((((everyContainer _container) apply {_x select 1}) - everyBackpack _container) - _addedContainers) select 0; + + // Items + { + private _itemCount = (_itemCargo select 1) select _forEachIndex; + _addedContainer addItemCargoGlobal [_x, _itemCount]; + } forEach (_itemCargo select 0); + + // Magazines (and their ammo count) + { + _addedContainer addMagazineAmmoCargo [_x select 0, 1, _x select 1]; + } forEach _magazinesAmmoCargo; + + // Weapons (and their attachments) + // Put attachments next to weapon, no command to put it directly onto a weapon when weapon is in a container + { + _x params ["_weapon", "_muzzle", "_pointer", "_optic", "_magazine", "_magazineGL", "_bipod"]; + + // weaponsItems magazineGL does not exist if not loaded (not even as empty array) + if (count _x < 7) then { + _bipod = _magazineGL; + _magazineGL = ""; + }; + + private _weapon = [_weapon] call CBA_fnc_getNonPresetClass; + _addedContainer addWeaponCargoGlobal [_weapon, 1]; + + _addedContainer addItemCargoGlobal [_muzzle, 1]; + _addedContainer addItemCargoGlobal [_pointer, 1]; + _addedContainer addItemCargoGlobal [_optic, 1]; + _addedContainer addItemCargoGlobal [_bipod, 1]; + + _magazine params [["_magazineClass", ""], ["_magazineAmmoCount", ""]]; + _addedContainer addMagazineAmmoCargo [_magazineClass, 1, _magazineAmmoCount]; + + _magazineGL params [["_magazineGLClass", ""], ["_magazineGLAmmoCount", ""]]; + _addedContainer addMagazineAmmoCargo [_magazineGLClass, 1, _magazineGLAmmoCount]; + } forEach _weaponsItemsCargo; + }; }; } forEach _allItemsType; diff --git a/addons/common/test_inventory.sqf b/addons/common/test_inventory.sqf index 751e6efd2..b59174a90 100644 --- a/addons/common/test_inventory.sqf +++ b/addons/common/test_inventory.sqf @@ -107,6 +107,15 @@ TEST_TRUE(_result,_funcName); TEST_TRUE(count (itemCargo _container) == 2,_funcName); clearItemCargoGlobal _container; +_container addItemCargoGlobal ["V_PlateCarrier1_rgr", 1]; +{ + (_x select 1) addItemCargoGlobal ["FirstAidKit", 5]; +} forEach (everyContainer _container); +_container addItemCargoGlobal ["FirstAidKit", 5]; +_result = [_container, "FirstAidKit", 5] call CBA_fnc_removeItemCargo; +TEST_TRUE(count (itemCargo _container) == 1 && count (itemCargo (((everyContainer _container) select 0) select 1)) == 5,_funcName); +clearItemCargoGlobal _container; + _funcName = "CBA_fnc_removeMagazineCargo"; LOG("Testing " + _funcName);