diff --git a/Missionframework/functions/fn_getSaveData.sqf b/Missionframework/functions/fn_getSaveData.sqf index 37e7cb930..836250037 100644 --- a/Missionframework/functions/fn_getSaveData.sqf +++ b/Missionframework/functions/fn_getSaveData.sqf @@ -15,6 +15,82 @@ Save data [ARRAY] */ +fnc_cleanSerializedItemsOfContainers = { + private _containers = _this select 0; + private _containerCount = count _containers; + private _items = _this select 1; + private _itemCount = count (_items select 0); + + private _deletionIndexes = []; + + if (_containerCount > 0 && _itemCount > 0) then { + for "_i" from 0 to _containerCount - 1 do { + private _containerClass = _containers select _i select 0; + + for "_j" from 0 to _itemCount - 1 do { + private _itemClass = _items select 0 select _j; + + if (_itemClass == _containerClass) then { + _deletionIndexes append [_j]; + }; + }; + }; + }; + + private _deletionCount = count _deletionIndexes; + private _deletedCount = 0; + if (_deletionCount > 0) then { + for "_i" from 0 to _deletionCount - 1 do { + private _index = (_deletionIndexes select _i) - _deletedCount; + + (_items select 0) deleteAt _index; + (_items select 1) deleteAt _index; + _deletedCount = _deletedCount + 1; + }; + }; + + _items; +}; + +fnc_serializeContainerCargo = { + private _return = []; + + private _target = _this select 0; + private _containers = everyContainer _target; + private _containerCount = count _containers; + + if (_containerCount > 0) then { + for "_i" from 0 to _containerCount - 1 do { + private _container = _containers select _i; + private _containerClass = _container select 0; + private _containerRef = _container select 1; + + private _weaponCargo = weaponsItemsCargo _containerRef; + private _magazineCargo = getMagazineCargo _containerRef; + private _itemCargo = getItemCargo _containerRef; + + _return append [[_containerClass, _weaponCargo, _magazineCargo, _itemCargo]]; + }; + }; + + _return; +}; + +fnc_serializeCargo = { + private _return = []; + private _target = _this select 0; + + private _weaponCargo = weaponsItemsCargo _target; + private _magazineCargo = getMagazineCargo _target; + private _itemCargo = getItemCargo _target; + private _containerCargo = [_target] call fnc_serializeContainerCargo; + + _itemCargo = [_containerCargo, _itemCargo] call fnc_cleanSerializedItemsOfContainers; + + _return = [_weaponCargo, _magazineCargo, _itemCargo, _containerCargo]; + _return; +}; + private _objectsToSave = []; private _resourceStorages = []; private _aiGroups = []; @@ -69,7 +145,7 @@ private ["_fobPos", "_fobObjects", "_grpUnits", "_fobMines"]; } forEach GRLIB_all_fobs; // Save all fetched objects -private ["_savedPos", "_savedVecDir", "_savedVecUp", "_class", "_hasCrew"]; +private ["_savedPos", "_savedVecDir", "_savedVecUp", "_class", "_hasCrew", "_inventory"]; { // Position data _savedPos = getPosWorld _x; @@ -77,6 +153,7 @@ private ["_savedPos", "_savedVecDir", "_savedVecUp", "_class", "_hasCrew"]; _savedVecUp = vectorUpVisual _x; _class = typeOf _x; _hasCrew = false; + _inventory = []; // Determine if vehicle is crewed if ((toLower _class) in KPLIB_b_allVeh_classes) then { @@ -90,7 +167,11 @@ private ["_savedPos", "_savedVecDir", "_savedVecUp", "_class", "_hasCrew"]; (!(_class in civilian_vehicles) || {_x getVariable ["KPLIB_seized", false]}) && (!((toLower _class) in KPLIB_o_allVeh_classes) || {_x getVariable ["KPLIB_captured", false]}) ) then { - _objectsToSave pushBack [_class, _savedPos, _savedVecDir, _savedVecUp, _hasCrew]; + + // Serialize inventory + _inventory = [_x] call fnc_serializeCargo; + + _objectsToSave pushBack [_class, _savedPos, _savedVecDir, _savedVecUp, _hasCrew, _inventory]; }; } forEach _allObjects; diff --git a/Missionframework/scripts/server/game/save_manager.sqf b/Missionframework/scripts/server/game/save_manager.sqf index 77cab506a..8ed69eea6 100644 --- a/Missionframework/scripts/server/game/save_manager.sqf +++ b/Missionframework/scripts/server/game/save_manager.sqf @@ -161,6 +161,93 @@ stats_vehicles_recycled = 0; _x setVariable ["KP_liberation_edenObject", true]; } forEach (allMissionObjects ""); +fnc_addWeaponsToCargo = { + private _target = _this select 0; + private _weapons = _this select 1; + + private _count = count (_weapons); + if (_count > 0) then { + for "_i" from 0 to _count - 1 do { + _weapon = _weapons select _i; + _target addWeaponWithAttachmentsCargoGlobal [_weapon, 1]; + }; + }; +}; + +fnc_addMagazinesToCargo = { + // Todo -> Magazine Ammo Count Restoration + + private _target = _this select 0; + private _magazines = _this select 1; + + private _count = count (_magazines select 1); + if (_count > 0) then { + for "_i" from 0 to _count - 1 do { + _magazineName = (_magazines select 0) select _i; + _magazineCount = (_magazines select 1) select _i; + _target addMagazineCargoGlobal [_magazineName, _magazineCount]; + }; + }; +}; + +fnc_addItemsToCargo = { + private _target = _this select 0; + private _items = _this select 1; + + private _count = count (_items select 1); + if (_count > 0) then { + for "_i" from 0 to _count - 1 do { + _itemName = (_items select 0) select _i; + _itemCount = (_items select 1) select _i; + _target addItemCargoGlobal [_itemName, _itemCount]; + }; + }; +}; + +fnc_addContainersToCargo = { + private _target = _this select 0; + private _containers = _this select 1; + private _containerCount = count _containers; + + for "_i" from 0 to _containerCount - 1 do { + private _thisContainer = _containers select _i; + + private _containerClass = _thisContainer select 0; + private _containerWeapons = _thisContainer select 1; + private _containerMagazines = _thisContainer select 2; + private _containerItems = _thisContainer select 3; + + if (_containerClass isKindOf "bag_base") then { + _target addBackpackCargoGlobal [_containerClass, 1]; + } else { + _target addItemCargoGlobal [_containerClass, 1]; + }; + + private _containerRef = (everyContainer _target) select ((count (everyContainer _target)) -1) select 1; + [_containerRef, _containerWeapons] call fnc_addWeaponsToCargo; + [_containerRef, _containerMagazines] call fnc_addMagazinesToCargo; + [_containerRef, _containerItems] call fnc_addItemsToCargo; + }; +}; + +fnc_loadCustomCargo = { + private _target = _this select 0; + private _weapons = (_this select 1) select 0; + private _magazines = (_this select 1) select 1; + private _items = (_this select 1) select 2; + private _containers = (_this select 1) select 3; + + clearWeaponCargoGlobal _target; + clearMagazineCargoGlobal _target; + clearItemCargoGlobal _target; + clearBackpackCargoGlobal _target; + + [_target, _weapons] call fnc_addWeaponsToCargo; + [_target, _magazines] call fnc_addMagazinesToCargo; + [_target, _items] call fnc_addItemsToCargo; + [_target, _containers] call fnc_addContainersToCargo; +}; + // Get possible save data private _saveData = profileNamespace getVariable GRLIB_save_key; @@ -321,7 +408,7 @@ if (!isNil "_saveData") then { private _object = objNull; { // Fetch data of saved object - _x params ["_class", "_pos", "_vecDir", "_vecUp", ["_hasCrew", false]]; + _x params ["_class", "_pos", "_vecDir", "_vecUp", ["_hasCrew", false], ["_inventory", []]]; // This will be removed if we reach a 0.96.7 due to more released Arma 3 DLCs until we finish 0.97.0 if !(((_saveData select 0) select 0) isEqualType 0) then { @@ -376,6 +463,11 @@ if (!isNil "_saveData") then { if ((unitIsUAV _object) || _hascrew) then { [_object] call KPLIB_fnc_forceBluforCrew; }; + + // Reload inventory if necessary + if ((count _inventory) == 4) then { + [_object, _inventory] call fnc_loadCustomCargo; + }; }; } forEach _objectsToSave;