celludriel 79 Posted March 1, 2017 (edited) Hey, I've been trying to find the best way to move all weapon, weapon addons, items and magazines of a player in a backpack. I've done a few attempts but each attempt manages to make duplicates of some items. Can you look with me at possible improvements ? Attempt 1: FAR_dropBackpack = { params ["_origin"]; _WEAPS = weapons _origin; _PWITEMS = primaryWeaponItems _origin; _SWITEMS = secondaryWeaponItems _origin; _HGITEMS = handgunItems _origin; _MAGS = magazines _origin; _PITEMS = items _origin; //filter stuff that shouldn't be in the arrays _WEAPS = [_WEAPS, ["Binocular","MineDetector","Rangefinder","Laserdesignator"]] call FAR_filterArray; /* diag_log format ["_WEAPS: %1", _WEAPS]; diag_log format ["_PWITEMS: %1", _PWITEMS]; diag_log format ["_SWITEMS: %1", _SWITEMS]; diag_log format ["_HGITEMS: %1", _HGITEMS]; diag_log format ["_MAGS: %1", _MAGS]; diag_log format ["_PITEMS: %1", _PITEMS]; */ _target = "B_Carryall_khk" createVehicle position _origin; { if(_x != "") then { _target addWeaponCargoGlobal [_x, 1] }; } forEach _WEAPS; { if(_x != "") then { _target addWeaponCargoGlobal [_x, 1] }; } forEach _HGITEMS; { if(_x != "") then { _target addMagazineCargoGlobal [_x, 1] }; } forEach _MAGS; { if(_x != "") then { _target addItemCargoGlobal [_x, 1] }; } forEach _PWITEMS; { if(_x != "") then { _target addItemCargoGlobal [_x, 1] }; } forEach _SWITEMS; { if(_x != "") then { _target addItemCargoGlobal [_x, 1] }; } forEach _PITEMS; }; Attempt 2 FAR_dropBackpackNew = { params ["_origin"]; private ["_inventory", "_target", "_tokens", "_category", "_type", "_PITEMS"]; _inventory = [_origin] call BIS_fnc_inv; _target = "B_Carryall_khk" createVehicle position _origin; { _tokens = (format ["%1", _x]) splitString "/"; _category = _tokens select 1; _type = _tokens select 2; if(_category == "CfgWeapons") then { _target addWeaponCargoGlobal [_type, 1] }; if(_category == "CfgMagazines") then { _target addMagazineCargoGlobal [_type, 1] }; } forEach _inventory; _PITEMS = items _origin; _PITEMS = [_PITEMS, ["Binocular", "MineDetector", "Rangefinder", "Laserdesignator"]] call FAR_filterArray; { if(_x != "") then { _target addItemCargoGlobal [_x, 1] }; } forEach _PITEMS; }; FAR_filterArray FAR_filterArray = { params ["_itemArray","_types"]; { _type = _x; { if (_x == _type) then { _itemArray = _itemArray - [_x]; }; } forEach _itemArray; } forEach _types; _itemArray }; The first attempt duplicates the primary weapon, the second attempt is duplicating the secondary weapon and loses all primary weapon addons :(. This is quite annoying. My main goal is just drop inventory from player in backpack after death and respawn. Edited March 2, 2017 by R0adki11 corrected spelling in thread title Share this post Link to post Share on other sites
celludriel 79 Posted March 2, 2017 Argh this is so frustrating to solve there are several factors working against me. You can get all weapons carried by the player, for example "srifle_DMR_01_ARCO_F". I then put it in the backpack with _target addWeaponCargoGlobal [_x, 1] ok great but now suppose the player had switched out optics with an ACO or maybe nothing. The weapon still spawns in the backpack with an ARCO attached cause that is it's template. Not the equipment he died with ! If I call [_origin] call BIS_fnc_inv; I get his weapons and magazines great, but when I call items _origin; I get everything he has in containers, including weapons it seems, causing duplicates of the same weapon to appear in the final backpack. There are some other functions I could have used https://community.bistudio.com/wiki/everyContainer Then loop over the containers and maybe take the objects in there and move them to the backpack [ ["V_PlateCarrier1_rgr",2bc06b00# 163955: dummyweapon.p3d], ["U_B_CombatUniform_mcam",2bc07900# 163954: dummyweapon.p3d] ] The dummyweapon.p3d placeholder there would have been great to do that HOWEVER, there is no method that I found able to move an object to a container. They all expect string as parameter that creates a new instance. So why even provide the placeholders in those objects if we can't do anything with them grrrrrr. Well I could drop them to the ground I guess ... Although not what I wanted to achieve ! but ok all my bitching aside, I'm just looking for a way to take weapons, items, and magazines a player carries , put them in a backpack and drop that backpack to the ground. I'll keep attempting other stuff, but any insights are very very VERY welcome :) Share this post Link to post Share on other sites
mrcurry 522 Posted March 2, 2017 I'll share how I assemble a players gear for saving across sessions for my guerrilla mission. This finds all gear a player is carrying including weapons and items within vests or uniforms stashed in a backpack.There's something in there as well about positional data but you can just ignore that. Spoiler private _obj = _args; //Retrieve vehicle information private _vehicleVarName = ""; private _vehicle = vehicle _obj; if(vehicle _obj != _obj) then { _vehicleVarName = vehicleVarName _vehicle; }; //Retrieve items private _cfgWeapons = configFile >> "CfgWeapons"; private _validItems = ["ItemCore", "DetectorCore"]; private _itemIsValid = { private _r = { _this isKindOf [_x, _cfgWeapons] } count _validItems; _r > 0 }; private _uniformItems = []; { if(_x call _itemIsValid) then { _uniformItems pushBack _x; }; } forEach uniformItems _obj; private _vestItems = []; { if(_x call _itemIsValid) then { _vestItems pushBack _x; }; } forEach vestItems _obj; private _backpackItems = []; { if(_x call _itemIsValid) then { _backpackItems pushBack _x; }; } forEach backpackItems _obj; //Retreieve mags in inventory only private _uniformMags = []; private _vestMags = []; private _backpackMags = []; { _x params [ "_class", "_ammo", "_loaded", "_type", "_location" ]; switch(_location) do { case "Uniform": { _uniformMags pushBack [_class, _ammo]; }; case "Vest": { _vestMags pushBack [_class, _ammo]; }; case "Backpack": { _backpackMags pushBack [_class, _ammo]; }; }; } forEach magazinesAmmoFull _obj; //Retrieve weapons in uniform vest and backpack private _uniformContainer = uniformContainer _obj; private _uniformWeapons = if(!isNull _uniformContainer) then { weaponsItems _uniformContainer } else { [] }; private _vestContainer = vestContainer _obj; private _vestWeapons = if(!isNull _vestContainer) then { weaponsItems _vestContainer } else { [] }; private _backpackContainer = backpackContainer _obj; private _backpackWeapons = if(!isNull _backpackContainer) then { weaponsItems _backpackContainer } else { [] }; //Retrieve weapons and loaded mags private _carriedWeapons = []; _carriedWeapons append _uniformWeapons; _carriedWeapons append _vestWeapons; _carriedWeapons append _backpackWeapons; private _equipedWeapons = []; private _carriedCount = count _carriedWeapons; { private _carried = false; private _i = 0; while {!_carried && _i < _carriedCount} do { _carried = _x isEqualTo (_carriedWeapons select _i); _i = _i + 1; }; if(!_carried) then { _equipedWeapons pushBack _x; _carriedWeapons set [_i, -1]; }; } forEach weaponsItems _obj; _ret = [ [ getPosATL _obj, getDir _obj, stance _obj, _vehicleVarName ], [ headgear _obj, goggles _obj, assignedItems _obj, [ uniform _obj, _uniformItems, _uniformMags, _uniformWeapons ], [ vest _obj, _vestItems, _vestMags, _vestWeapons ], [ (backpack _obj) call BIS_fnc_basicBackpack, _backpackItems, _backpackMags, _backpackWeapons ], _equipedWeapons ] ]; And here's the relevant bits on how I go about giving it back to the player, _gearData refers to the second element of the return from above. You'd have to extrapolate from that how to get it all in a backpack since all I do is add it back on the player. Spoiler _gearData params [ "_headgear", "_goggles", "_assignedItems", "_uniform", "_vest", "_backpack", "_equipedWeapons" ]; _obj addHeadgear _headgear; _obj addGoggles _goggles; { _obj addWeapon _x } forEach _assignedItems; //Remove exising gear removeUniform _obj; removeVest _obj; removeBackpack _obj; removeHeadgear _obj; removeGoggles _obj; removeAllWeapons _obj; {_obj unassignItem _x} forEach assignedItems _obj; //Add wearables and their content /* Headgear, Goggles and assigned items */ _obj addHeadgear _headgear; _obj addGoggles _goggles; { _obj addWeapon _x } forEach _assignedItems; DEBUG_LOG("Adding equiped weapons"); /* Equiped weapons */ { private _elem = _x; private _w = ""; { if(_forEachIndex == 0) then { _w = _x; _obj addWeapon _w; } else { switch(typeName _x) do { case "STRING": { if(_x != "") then { _obj addWeaponItem [_w , _x]; }; }; case "ARRAY": { _obj addWeaponItem [_w, _x]; }; }; }; } forEach _elem; } forEach _equipedWeapons; /* Uniform */ _uniform params [ "_uniform", "_uniformItems", "_uniformMags", "_uniformWeapons" ]; DEBUG_LOG("Adding uniform"); _obj addUniform _uniform; DEBUG_LOG("Adding uniform items"); {_obj addItemToUniform _x} forEach _uniformItems; DEBUG_LOG("Adding uniform magazines"); private _uniformObj = uniformContainer _obj; { _uniformObj addMagazineAmmoCargo [_x select 0, 1 , _x select 1]; } forEach _uniformMags; DEBUG_LOG("Adding uniform weapons"); { private _elem = _x; { switch(typeName _x) do { case "STRING": { if(_x != "") then { if(_x isKindOf ["ItemCore", configFile >> "CfgWeapons"]) then { _obj addItemToUniform _x; } else { private _baseWeapon = (_x call BIS_fnc_weaponComponents) select 0; _obj addItemToUniform _baseWeapon; }; }; }; case "ARRAY": { if(count _x > 0) then { _uniformObj addMagazineAmmoCargo [_x select 0, 1, _x select 1]; }; }; }; } forEach _elem; } forEach _uniformWeapons; /* Vest */ _vest params [ "_vest", "_vestItems", "_vestMags", "_vestWeapons" ]; DEBUG_LOG("Adding vest"); _obj addVest _vest; DEBUG_LOG("Adding vest items"); {_obj addItemToVest _x} forEach _vestItems; DEBUG_LOG("Adding vest magazines"); private _vestObj = vestContainer _obj; { _vestObj addMagazineAmmoCargo [_x select 0, 1 , _x select 1]; } forEach _vestMags; DEBUG_LOG("Adding vest weapons"); { private _elem = _x; { switch(typeName _x) do { case "STRING": { if(_x != "") then { if(_x isKindOf ["ItemCore", configFile >> "CfgWeapons"]) then { _obj addItemToVest _x; } else { private _baseWeapon = (_x call BIS_fnc_weaponComponents) select 0; _obj addItemToVest _baseWeapon; }; }; }; case "ARRAY": { if(count _x > 0) then { _vestObj addMagazineAmmoCargo [_x select 0, 1, _x select 1]; }; }; }; } forEach _elem; } forEach _vestWeapons; /* Backpack */ _backpack params [ "_backpack", "_backpackItems", "_backpackMags", "_backpackWeapons" ]; DEBUG_LOG("Adding backpack"); _obj addBackpack _backpack; DEBUG_LOG("Adding backpack items"); {_obj addItemToBackpack _x} forEach _backpackItems; DEBUG_LOG("Adding backpack magazines"); private _backpackObj = backpackContainer _obj; { _backpackObj addMagazineAmmoCargo [_x select 0, 1 , _x select 1]; } forEach _backpackMags; DEBUG_LOG("Adding backpack weapons"); { private _elem = _x; { switch(typeName _x) do { case "STRING": { if(_x != "") then { if(_x isKindOf ["ItemCore", configFile >> "CfgWeapons"]) then { _obj addItemToBackpack _x; } else { private _baseWeapon = (_x call BIS_fnc_weaponComponents) select 0; _obj addItemToBackpack _baseWeapon; }; }; }; case "ARRAY": { if(count _x > 0) then { _backpackObj addMagazineAmmoCargo [_x select 0, 1, _x select 1]; }; }; }; } forEach _elem; } forEach _backpackWeapons; if ( (primaryWeapon _obj) != "") then { private _type = primaryWeapon _obj; private _muzzles = getArray(configFile >> "cfgWeapons" >> _type >> "muzzles"); if (count _muzzles > 1) then { _obj selectWeapon (_muzzles select 0); } else { _obj selectWeapon _type; }; }; Hope that helps. 1 Share this post Link to post Share on other sites
serena 151 Posted March 2, 2017 4 minutes ago, mrcurry said: private _baseWeapon = (_x call BIS_fnc_weaponComponents) select 0; _obj addItemToBackpack _baseWeapon; https://community.bistudio.com/wiki/BIS_fnc_baseWeapon 1 Share this post Link to post Share on other sites
celludriel 79 Posted March 2, 2017 1 hour ago, mrcurry said: Hope that helps. It does it's giving me more insights and I can extrapolate to my own implimentation. I'm just a little frustrated BI doesn't have something simpel like this by default, getInventory , moveInventory ... based on objects instead of string and new instancing :( Share this post Link to post Share on other sites
mrcurry 522 Posted March 2, 2017 1 hour ago, serena said: https://community.bistudio.com/wiki/BIS_fnc_baseWeapon I'm using BIS_fnc_weaponComponents for a very good reason. If you input the tropic MX class into BIS_fnc_baseWeapon it will return the basic weapon only. i.e. it strips out the camo and/or colour variants. BIS_fnc_weaponComponents however only separates the main weapon from its attachments giving you the weapon with correct paintjob but sans attachments. Since I retrieve and handle the weapon attachments elsewhere the only thing I need is the first element, the weapon. 1 Share this post Link to post Share on other sites
celludriel 79 Posted March 2, 2017 If people would start to convert my missions to work with CUP or RHS would BIS_fnc_baseWeapon or BIS_fnc_weaponComponents still work ? Is the base weapon an attribute of a complex template ? Share this post Link to post Share on other sites
serena 151 Posted March 2, 2017 5 minutes ago, mrcurry said: If you input the tropic MX class into BIS_fnc_baseWeapon it will return the basic weapon only. i.e. it strips out the camo and/or colour variants systemChat ("arifle_MX_khk_F" call Bis_fnc_BaseWeapon); systemChat ("arifle_SPAR_01_GL_blk_F" call Bis_fnc_BaseWeapon); // Output: // arifle_MX_khk_F // arifle_SPAR_01_GL_blk_F My function is working properly. Did I do something wrong? Share this post Link to post Share on other sites
serena 151 Posted March 2, 2017 13 minutes ago, celludriel said: If people would start to convert my missions to work with CUP or RHS would BIS_fnc_baseWeapon or BIS_fnc_weaponComponents still work ? Is the base weapon an attribute of a complex template ? BIS_fnc_baseWeapon = { private _class = _this param [0,"",[""]]; private _cfg = configFile >> "cfgWeapons" >> _class; if !(isClass _cfg) exitWith { if (_class != "") then {["Class '%1' not found in CfgWeapons", _class] call BIS_fnc_error}; _class }; private _base = getText (_cfg >> "baseWeapon"); if (isClass (configFile >> "cfgWeapons" >> _base)) exitWith {_base}; private _return = _class; { if (count (_x >> "linkeditems") == 0) exitwith {_return = configname _x;}; } foreach (_cfg call BIS_fnc_returnParents); _return; }; 1 Share this post Link to post Share on other sites
celludriel 79 Posted March 2, 2017 Well I'm at work so couldn't check the functions in the editor private _base = getText (_cfg >> "baseWeapon"); if (isClass (configFile >> "cfgWeapons" >> _base)) exitWith {_base}; this confirms it though it is a an attribute on the weapon template Share this post Link to post Share on other sites
mrcurry 522 Posted March 2, 2017 45 minutes ago, serena said: systemChat ("arifle_MX_khk_F" call Bis_fnc_BaseWeapon); systemChat ("arifle_SPAR_01_GL_blk_F" call Bis_fnc_BaseWeapon); // Output: // arifle_MX_khk_F // arifle_SPAR_01_GL_blk_F My function is working properly. Did I do something wrong? Ah sweet, they must have updated it then since I wrote that. Good to have it work as expected. Cheers for bringing it to my attention. Edit: @celludriel Based on a small sample of infantry weapons I can confirm BIS_fnc_baseWeapon works well with CUP as well. RHS is most likely the same. Any mod that applies inheritance in the same way as the base game should be fine. 1 Share this post Link to post Share on other sites
celludriel 79 Posted March 2, 2017 Well thanks to all of you I got the solution here it is. I had to tweak your code a little @mrcurry cause my use case is just slightly different. I made a new function fn_getUnitInventory params ["_unit"]; [["Calling getUnitInventory"]] call CTISHR_fnc_ctiLog; [["_unit: %1", _unit]] call CTISHR_fnc_ctiLog; //Retrieve items private _itemIsValid = { private _r = { _this isKindOf [_x, configFile >> "CfgWeapons"] } count ["ItemCore", "DetectorCore"]; _r > 0 }; [["Initialised _itemIsValid"]] call CTISHR_fnc_ctiLog; private _items = []; private _magazines = []; private _carriedWeapons = []; private _equipedWeapons = []; private _allWeapons = []; { if(_x call _itemIsValid) then { _items pushBack _x; }; } forEach uniformItems _unit; { if(_x call _itemIsValid) then { _items pushBack _x; }; } forEach vestItems _unit; { if(_x call _itemIsValid) then { _items pushBack _x; }; } forEach backpackItems _unit; [["_items: %1", _items]] call CTISHR_fnc_ctiLog; //Retreieve mags in inventory only { _x params [ "_class", "_ammo", "_loaded", "_type", "_location" ]; switch(_location) do { case "Uniform": { _magazines pushBack [_class, _ammo]; }; case "Vest": { _magazines pushBack [_class, _ammo]; }; case "Backpack": { _magazines pushBack [_class, _ammo]; }; }; } forEach magazinesAmmoFull _unit; [["_magazines: %1", _magazines]] call CTISHR_fnc_ctiLog; //Retrieve weapons in uniform vest and backpack private _uniformContainer = uniformContainer _unit; private _uniformWeapons = if(!isNull _uniformContainer) then { weaponsItems _uniformContainer } else { [] }; private _vestContainer = vestContainer _unit; private _vestWeapons = if(!isNull _vestContainer) then { weaponsItems _vestContainer } else { [] }; private _backpackContainer = backpackContainer _unit; private _backpackWeapons = if(!isNull _backpackContainer) then { weaponsItems _backpackContainer } else { [] }; //Retrieve weapons and loaded mags _carriedWeapons append _uniformWeapons; _carriedWeapons append _vestWeapons; _carriedWeapons append _backpackWeapons; private _carriedCount = count _carriedWeapons; { private _carried = false; private _i = 0; while {!_carried && _i < _carriedCount} do { _carried = _x isEqualTo (_carriedWeapons select _i); _i = _i + 1; }; if(!_carried) then { _equipedWeapons pushBack _x; _carriedWeapons set [_i, -1]; }; } forEach weaponsItems _unit; _allWeapons pushBack _uniformWeapons; _allWeapons pushBack _vestWeapons; _allWeapons pushBack _backpackWeapons; _allWeapons pushBack _equipedWeapons; [["_allWeapons: %1", _allWeapons]] call CTISHR_fnc_ctiLog; _ret = [ _items, _magazines, _allWeapons ]; _ret You'll recognise a lot of your work just my output is different I only take back items magazines and weapons no matter where they come from. And this is how I make the backpack FAR_dropBackpack = { params ["_origin"]; private ["_inventory", "_target", "_items", "_magazines", "_allWeapons"]; _inventory = [_origin] call CTISRV_fnc_getUnitInventory; diag_log format ["_inventory: %1", _inventory]; _target = "B_Carryall_khk" createVehicle position _origin; _items = _inventory select 0; _magazines = _inventory select 1; _allWeapons = _inventory select 2; { if(_x != "") then { _target addItemCargoGlobal [_x, 1]; }; } forEach _items; { if(count _x > 0) then { _target addMagazineCargoGlobal [_x select 0, 1]; }; } forEach _magazines; { if(count _x > 0) then { { private ["_weapon", "_surpressor", "_laser", "_optic", "_magazine", "_bipod"]; _weapon = _x select 0; if(_weapon != "" || _weapon != "Binocular" || _weapon != "hgun_P07_F") then { _target addWeaponCargoGlobal [_weapon call BIS_fnc_BaseWeapon, 1]; }; _surpressor = _x select 1; if(_surpressor != "") then { _target addItemCargoGlobal [_surpressor, 1]; }; _laser = _x select 2; if(_laser != "") then { _target addItemCargoGlobal [_laser, 1]; }; _optic = _x select 3; if(_optic != "") then { _target addItemCargoGlobal [_optic, 1]; }; _magazine = _x select 4; if(count _magazine > 0) then { _target addMagazineCargoGlobal [_magazine select 0, 1]; }; _bipod = _x select 5; if(_bipod != "") then { _target addItemCargoGlobal [_bipod, 1]; }; } forEach _x; }; } forEach _allWeapons; }; I skip Binoculars and the handgun because of my mission (players spawn with them) so other then that this is pretty reusable by other people I believe. so yay problem solved Thanks all ! 1 Share this post Link to post Share on other sites