From e7b1b4c8cb336f557a2463ba05d21b52cd82ef1f Mon Sep 17 00:00:00 2001
From: johnb432 <58661205+johnb432@users.noreply.github.com>
Date: Wed, 5 Jun 2024 21:59:54 +0200
Subject: [PATCH] Magazine removal

---
 .../fnc_detonateAmmunitionServerLoop.sqf      | 67 ++++++++++++++++---
 1 file changed, 59 insertions(+), 8 deletions(-)

diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf
index 7fdcedda51..34124cc70d 100644
--- a/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf
+++ b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf
@@ -22,7 +22,15 @@ params ["_object", "_destroyWhenFinished", "_source", "_instigator"];
 
 if (isNull _object) exitWith {};
 
-(_object getVariable QGVAR(cookoffMagazines)) params ["_magazines", "_totalAmmo"];
+// If the variable is set, it won't remove magazines
+private _objectAmmo = _object getVariable QGVAR(cookoffMagazines);
+private _removeAmmoDuringCookoff = isNil "_objectAmmo";
+
+if (_removeAmmoDuringCookoff) then {
+    _objectAmmo = _object call FUNC(getVehicleAmmo);
+};
+
+_objectAmmo params ["_magazines", "_totalAmmo"];
 
 private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []};
 
@@ -54,6 +62,7 @@ if (
 
     // Reset variables, so the object can detonate its ammo again
     _object setVariable [QGVAR(cookoffMagazines), nil];
+    _object setVariable [QGVAR(virtualMagazines), nil];
     _object setVariable [QGVAR(isAmmoDetonating), nil, true];
 
     // If done, destroy the object if necessary
@@ -64,27 +73,69 @@ if (
 
 private _magazineIndex = floor random (count _magazines);
 private _magazine = _magazines select _magazineIndex;
-_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile"];
+_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile", "_magazineInfo"];
 
 // Make sure ammo is at least 0
 _ammoCount = _ammoCount max 0;
 
 // Remove some ammo, which will be detonated
 private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration)));
+private _newAmmoCount = _ammoCount - _removed;
 
-_ammoCount = _ammoCount - _removed;
+// Remove ammo from magazines if enabled
+if (_removeAmmoDuringCookoff) then {
+    switch (true) do {
+        // Turret magazines
+        case (_magazineInfo isEqualType []): {
+            // Remove loaded magazine
+            if (_newAmmoCount <= 0) then {
+                [QEGVAR(common,removeMagazineTurret), [_object, _magazineClassname, _magazineInfo], _object, _magazineInfo] call CBA_fnc_turretEvent;
+            } else {
+                [QEGVAR(common,setMagazineTurretAmmo), [_object, _magazineClassname, _newAmmoCount, _magazineInfo], _object, _magazineInfo] call CBA_fnc_turretEvent;
+            };
+        };
+        // Inventory magazines
+        case (_magazineInfo isEqualTo false): {
+            // Remove selected magazine
+            _object addMagazineAmmoCargo [_magazineClassname, -1, _ammoCount];
 
-if (_ammoCount <= 0) then {
-    _magazines deleteAt _magazineIndex;
+            // Add a new one with reduced ammo back
+            if (_newAmmoCount > 0) then {
+                _object addMagazineAmmoCargo [_magazineClassname, 1, _newAmmoCount];
+            };
+        };
+        // Virtual magazines
+        case (_magazineInfo isEqualTo true): {
+            // Find the virtual magazines and update its count
+            private _virtualAmmo = _object getVariable QGVAR(virtualMagazines);
+            _magazineIndex = _virtualAmmo findIf {(_x select 0) == _magazineClassname};
+
+            if (_magazineIndex == -1) exitWith {
+                TRACE_1("no virtual magazine",_magazineClass);
+            };
+
+            if (_newAmmoCount <= 0) then {
+                _virtualAmmo deleteAt _magazineIndex;
+            } else {
+                (_virtualAmmo select _magazineIndex) set [1, _newAmmoCount]; // remove ammo that was detonated
+            };
+        };
+    };
 } else {
-    _magazine set [1, _ammoCount]; // remove ammo that was detonated
+    if (_newAmmoCount <= 0) then {
+        _magazines deleteAt _magazineIndex;
+    } else {
+        _magazine set [1, _newAmmoCount]; // remove ammo that was detonated
+    };
 };
 
 private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1;
 TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation);
-_totalAmmo = _totalAmmo - _removed;
 
-_object setVariable [QGVAR(cookoffMagazines), [_magazines, _totalAmmo]];
+// Update total ammo value if mags aren't being removed (if they are, an updated total will be gotten upon the next ammo detonation iteration)
+if (!_removeAmmoDuringCookoff) then {
+    _objectAmmo set [1, _totalAmmo - _removed];
+};
 
 // Get magazine info, which is used to spawn projectiles
 private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname;