diff --git a/addons/magazinerepack/CfgEventHandlers.hpp b/addons/magazinerepack/CfgEventHandlers.hpp
index f0a9f14d91..b928bc2de6 100644
--- a/addons/magazinerepack/CfgEventHandlers.hpp
+++ b/addons/magazinerepack/CfgEventHandlers.hpp
@@ -1,4 +1,3 @@
-
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preInit));
diff --git a/addons/magazinerepack/CfgSounds.hpp b/addons/magazinerepack/CfgSounds.hpp
new file mode 100644
index 0000000000..bc1d0fe0ee
--- /dev/null
+++ b/addons/magazinerepack/CfgSounds.hpp
@@ -0,0 +1,15 @@
+class CfgSounds
+{
+ class GVAR(soundMagazineFinished)
+ {
+ name = QGVAR(soundMagazineFinished);
+ sound[]={QUOTE(PATHTOF(sounds\magrepack_finished.wav)),1,1};
+ titles[]={};
+ };
+ class GVAR(soundRoundFinished)
+ {
+ name = QGVAR(soundRoundFinished);
+ sound[] = {QUOTE(PATHTOF(sounds\magrepack_single.wav)),1,1};
+ titles[] = {};
+ };
+};
\ No newline at end of file
diff --git a/addons/magazinerepack/CfgVehicles.hpp b/addons/magazinerepack/CfgVehicles.hpp
index ecb732f8fd..acd1c76c3d 100644
--- a/addons/magazinerepack/CfgVehicles.hpp
+++ b/addons/magazinerepack/CfgVehicles.hpp
@@ -1,18 +1,17 @@
-
class CfgVehicles {
- class Man;
- class CAManBase: Man {
- class ACE_SelfActions {
- class ACE_RepackMagazines {
- displayName = "$STR_ACE_MagazineRepack_RepackMagazines";
- condition = QUOTE(true);
- statement = QUOTE([_player] call FUNC(magazineRepack));
- showDisabled = 0;
- priority = -2;
- icon = PATHTOF(UI\repack_ca.paa);
- hotkey = "R";
- enableInside = 1;
- };
+ class Man;
+ class CAManBase: Man {
+ class ACE_SelfActions {
+ class ACE_RepackMagazines {
+ displayName = "$STR_ACE_MagazineRepack_RepackMagazines";
+ condition = QUOTE(true);
+ statement = QUOTE([_player] call FUNC(openSelectMagazineUI));
+ showDisabled = 0;
+ priority = -2;
+ icon = QUOTE(PATHTOF(UI\repack_ca.paa));
+ hotkey = "R";
+ enableInside = 1;
+ };
+ };
};
- };
};
diff --git a/addons/magazinerepack/README.md b/addons/magazinerepack/README.md
index 49a3c9d531..28b7c3115a 100644
--- a/addons/magazinerepack/README.md
+++ b/addons/magazinerepack/README.md
@@ -3,10 +3,10 @@ ace_magazinerepack
Adds the ability to consolidate multiple half-empty magazines.
-
## Maintainers
The people responsible for merging changes to this component or answering potential questions.
- [commy2](https://github.com/commy2)
- [esteldunedain](https://github.com/esteldunedain)
+- [PabstMirror](https://github.com/PabstMirror)
diff --git a/addons/magazinerepack/XEH_preInit.sqf b/addons/magazinerepack/XEH_preInit.sqf
index 5caba1ffac..e2dfd721f3 100644
--- a/addons/magazinerepack/XEH_preInit.sqf
+++ b/addons/magazinerepack/XEH_preInit.sqf
@@ -2,8 +2,9 @@
ADDON = false;
-PREP(magazineRepack);
-PREP(magazineRepackCallback);
+PREP(magazineRepackProgress);
PREP(openSelectMagazineUI);
+PREP(simulateRepackEvents);
+PREP(startRepackingMagazine);
ADDON = true;
diff --git a/addons/magazinerepack/config.cpp b/addons/magazinerepack/config.cpp
index 5f2c6edc7d..2df0d62bff 100644
--- a/addons/magazinerepack/config.cpp
+++ b/addons/magazinerepack/config.cpp
@@ -13,6 +13,7 @@ class CfgPatches {
};
#include "CfgEventHandlers.hpp"
+#include "CfgSounds.hpp"
#include "CfgVehicles.hpp"
class ACE_Parameters_Numeric {
diff --git a/addons/magazinerepack/functions/fnc_magazineRepack.sqf b/addons/magazinerepack/functions/fnc_magazineRepack.sqf
deleted file mode 100644
index 472b80e2bd..0000000000
--- a/addons/magazinerepack/functions/fnc_magazineRepack.sqf
+++ /dev/null
@@ -1,77 +0,0 @@
-// by commy2, esteldunedain
-#include "script_component.hpp"
-
-private ["_unit", "_magazines", "_ammos", "_repackTime", "_magazine", "_ammo", "_count", "_index", "_i", "_j", "_ammoToTransfer", "_ammoAvailable", "_ammoNeeded"];
-
-_unit = _this select 0;
-
-_magazines = [];
-_ammos = [];
-_repackTime = [];
-
-// get all mags and ammo count
-{
- _magazine = _x select 0;
- _ammo = _x select 1;
-
- _count = getNumber (configfile >> "CfgMagazines" >> _magazine >> "count");
-
- if (_ammo != _count && {_count > 1}) then { // additional checks here
- if !(_magazine in _magazines) then {
- _index = count _magazines;
- _magazines set [_index, _magazine];
- _ammos set [_index, [_ammo]];
- } else {
- _index = _magazines find _magazine;
- _ammos set [_index, (_ammos select _index) + [_ammo]];
- };
- };
-} forEach magazinesAmmoFull _unit;
-
-// Remove invalid magazines
-{
- if (count _x < 2) then {
- _magazines set [_forEachIndex, -1];
- _ammos set [_forEachIndex, [-1]];
- };
-} forEach _ammos;
-_magazines = _magazines - [-1];
-_ammos = _ammos - [[-1]];
-
-{
- // Calculate actual ammo to transfer during repack
- _count = getNumber (configfile >> "CfgMagazines" >> (_magazines select _forEachIndex) >> "count");
-
- // Sort Ascending
- _list = _x call BIS_fnc_sortNum;
-
- ["MagazineRepack", _list] call EFUNC(common,log);
-
- _i = 0;
- _j = count _x - 1;
- _ammoToTransfer = 0;
- _ammoAvailable = 0;
- while {_i < _j} do {
- _ammoNeeded = _count - (_list select _j);
- _exit = false;
- while {_i < _j && {!_exit}} do {
- _ammoAvailable = _list select _i;
- if (_ammoAvailable >= _ammoNeeded) then {
- _list set [_i, _ammoAvailable - _ammoNeeded];
- _ammoToTransfer = _ammoToTransfer + _ammoNeeded;
- _exit = true;
- } else {
- _ammoNeeded = _ammoNeeded - _ammoAvailable;
- _ammoToTransfer = _ammoToTransfer + _ammoAvailable;
- _i = _i + 1;
- };
- };
- _j = _j - 1;
- };
-
- _repackTime set [_forEachIndex, _ammoToTransfer * GVAR(TimePerAmmo) + (count _x) * GVAR(TimePerMagazine)];
-} forEach _ammos;
-
-["MagazineRepack", [_magazines, _repackTime]] call EFUNC(common,log);
-
-[_unit, _magazines, _repackTime] call FUNC(openSelectMagazineUI);
diff --git a/addons/magazinerepack/functions/fnc_magazineRepackCallback.sqf b/addons/magazinerepack/functions/fnc_magazineRepackCallback.sqf
deleted file mode 100644
index f209806f9c..0000000000
--- a/addons/magazinerepack/functions/fnc_magazineRepackCallback.sqf
+++ /dev/null
@@ -1,106 +0,0 @@
-// by commy2
-#include "script_component.hpp"
-
-private ["_unit", "_magazine", "_ammo", "_ammoCount", "_fullMagazinesCount", "_restAmmo", "_isLoaded", "_weapon", "_reloadAction", "_text", "_picture"];
-
-_unit = ACE_player; //_this select 0;
-_magazine = _this select 1;
-
-// exit if the last magazine of this type was taken out of the backpack
-if !(_magazine in magazines _unit) exitWith {};
-
-// get current ammo count
-_ammo = 0;
-{
- if (_x select 0 == _magazine) then {
- _ammo = _ammo + (_x select 1);
- };
-} forEach magazinesAmmoFull _unit;
-
-// how many rounds fit in one mag
-_ammoCount = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count");
-
-// calculate new vaules
-_fullMagazinesCount = floor (_ammo / _ammoCount);
-_restAmmo = _ammo - _fullMagazinesCount * _ammoCount;
-
-// remove old magazines
-_unit removeMagazines _magazine;
-
-_isLoaded = false;
-// reload rifle
-if (_magazine in primaryWeaponMagazine _unit) then {
- _weapon = primaryWeapon _unit;
-
- if (_fullMagazinesCount > 0) then {
- _unit setAmmo [_weapon, _ammoCount];
- _fullMagazinesCount = _fullMagazinesCount - 1;
- } else {
- _unit setAmmo [_weapon, _restAmmo];
- _restAmmo = 0;
- };
-
- if (_weapon == currentWeapon _unit) then {
- _reloadAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction");
- _unit playActionNow _reloadAction;
- };
-
- _isLoaded = true;
-};
-
-// reload pistol
-if (_magazine in handgunMagazine _unit) then {
- _weapon = handgunWeapon _unit;
-
- if (_fullMagazinesCount > 0) then {
- _unit setAmmo [_weapon, _ammoCount];
- _fullMagazinesCount = _fullMagazinesCount - 1;
- } else {
- _unit setAmmo [_weapon, _restAmmo];
- _restAmmo = 0;
- };
-
- if (_weapon == currentWeapon _unit) then {
- _reloadAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction");
- _unit playActionNow _reloadAction;
- };
-
- _isLoaded = true;
-};
-
-// reload rocket launcher (just in case ...)
-if (_magazine in secondaryWeaponMagazine _unit) then {
- _weapon = secondaryWeapon _unit;
-
- if (_fullMagazinesCount > 0) then {
- _unit setAmmo [_weapon, _ammoCount];
- _fullMagazinesCount = _fullMagazinesCount - 1;
- } else {
- _unit setAmmo [_weapon, _restAmmo];
- _restAmmo = 0;
- };
-
- if (_weapon == currentWeapon _unit) then {
- _reloadAction = getText (configFile >> "CfgWeapons" >> _weapon >> "reloadAction");
- _unit playActionNow _reloadAction;
- };
-
- _isLoaded = true;
-};
-
-// add new magazines
-for "_a" from 1 to _fullMagazinesCount do {
- _unit addMagazine _magazine;
-};
-
-if (_restAmmo > 0) then {
- _unit addMagazine [_magazine, _restAmmo];
-};
-
-// display text if successful
-_text = format [localize "STR_ACE_MagazineRepack_RepackedMagazinesDetail", [_fullMagazinesCount, _fullMagazinesCount + 1] select _isLoaded, _restAmmo];
-_picture = getText (configFile >> "CfgMagazines" >> _magazine >> "picture");
-
-_text = parseText format ["
%2
%3", _picture, localize "STR_ACE_MagazineRepack_RepackedMagazines", _text];
-
-[_text] call EFUNC(common,displayTextStructured);
diff --git a/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf b/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf
new file mode 100644
index 0000000000..f965305eda
--- /dev/null
+++ b/addons/magazinerepack/functions/fnc_magazineRepackProgress.sqf
@@ -0,0 +1,70 @@
+// by commy2, esteldunedain
+#include "script_component.hpp"
+
+PARAMS_3(_args,_elapsedTime,_totalTime);
+EXPLODE_3_PVT(_args,_magazineClassname,_lastAmmoCount,_simEvents);
+
+if ((count _simEvents) == 0) exitWith {ERROR("No Event"); false};
+EXPLODE_3_PVT((_simEvents select 0),_nextEventTime,_nextEventType,_nextEventMags);
+
+
+
+if (_nextEventTime > _elapsedTime) exitWith {true};//waiting on next event
+systemChat format ["Event %1-%2-%3", _nextEventTime,_nextEventType,_nextEventMags];
+
+
+//Verify we aren't missing any ammo
+_currentAmmoCount = [];
+{
+ EXPLODE_2_PVT(_x,_xClassname,_xCount);
+ if (_xClassname == _magazineClassname) then {
+ _currentAmmoCount pushBack _xCount;
+ };
+} forEach (magazinesAmmo ACE_player); //only inventory mags
+
+_addedMagazines = +_currentAmmoCount;
+_missingAmmo = false;
+{
+ if (_x > 0) then {
+ _index = _addedMagazines find _x;
+ if (_index != -1) then {
+ _addedMagazines deleteAt _index;
+ } else {
+ _missingAmmo = true;
+ };
+ };
+} forEach _lastAmmoCount;
+
+if (_missingAmmo) exitWith {false}; //something removed ammo that was being repacked
+if ((count _addedMagazines) > 0) then {
+ TRACE_1("Added Magazine While Repacking",_addedMagazines);
+};
+
+_updateMagazinesOnPlayer = {
+ systemChat format ["Updating mags"];
+ _newMagazineList = _addedMagazines + _nextEventMags;
+ ACE_player removeMagazines _magazineClassname;
+ {
+ if (_x > 0) then {
+ ACE_player addMagazine [_magazineClassname, _x];
+ };
+ } forEach _newMagazineList;
+ _args set [1, _nextEventMags];
+};
+
+
+if (_nextEventType == 0) then {
+ systemChat "reloading bullet";
+ playSound QGVAR(soundMagazineFinished);
+ if (((count _simEvents) % 3) == 0) then {
+ call _updateMagazinesOnPlayer;
+ };
+} else {
+ systemChat "Moving to next mag";
+ playSound QGVAR(soundRoundFinished);
+ call _updateMagazinesOnPlayer;
+};
+
+_simEvents deleteAt 0; //pop off the event
+
+true;
diff --git a/addons/magazinerepack/functions/fnc_openSelectMagazineUI.sqf b/addons/magazinerepack/functions/fnc_openSelectMagazineUI.sqf
index b1a31c266c..931a0149cf 100644
--- a/addons/magazinerepack/functions/fnc_openSelectMagazineUI.sqf
+++ b/addons/magazinerepack/functions/fnc_openSelectMagazineUI.sqf
@@ -1,40 +1,47 @@
-// by commy2
+// by commy2, esteldunedain
#include "script_component.hpp"
-private ["_unit", "_magazines", "_repackTime", "_listIDC", "_count", "_index", "_magazine", "_time", "_displayName", "_picture"];
+private ["_unit", "_magazines", "_ammos", "_repackTime", "_magazine", "_ammo", "_count", "_index", "_i", "_j", "_ammoToTransfer", "_ammoAvailable", "_ammoNeeded"];
-_unit = _this select 0;
-_magazines = _this select 1;
-_repackTime = _this select 2;
+PARAMS_1(_unit);
-_count = count _magazines;
+_unitMagazines = [];
+_unitMagCounts = [];
+
+// get all mags and ammo count
+{
+ _xClassname = _x select 0;
+ _xCount = _x select 1;
+ _fullMagazineCount = getNumber (configfile >> "CfgMagazines" >> _xClassname >> "count");
+
+ if ((_xCount != _fullMagazineCount) && {_xCount > 1}) then {//for every partial magazine
+ _index = _unitMagazines find _xClassname;
+ if (_index == -1) then {
+ _unitMagazines pushBack _xClassname;
+ _unitMagCounts pushBack [_xCount];
+ } else {
+ (_unitMagCounts select _index) pushBack _xCount;
+ };
+ };
+} forEach magazinesAmmoFull _unit;
_actions = [localize "STR_ACE_MagazineRepack_SelectMagazineMenu", localize "STR_ACE_MagazineRepack_SelectMagazine"] call EFUNC(interaction,prepareSelectMenu);
-for "_index" from 0 to (_count - 1) do {
- _magazine = _magazines select _index;
- _time = _repackTime select _index;
- _displayName = getText (configFile >> "CfgMagazines" >> _magazine >> "displayName");
- _picture = getText (configFile >> "CfgMagazines" >> _magazine >> "picture");
- _actions = [
- _actions,
- _displayName,
- _picture,
- [str _unit, _magazine, _time]
- ] call EFUNC(interaction,addSelectableItem);
-};
+
+systemChat format ["%1 - %2", _unitMagazines, _unitMagCounts];
+
+{
+ if ((count (_unitMagCounts select _forEachIndex)) >= 2) then {// Ignore invalid magazines types (need 2+ partial mags to do anything)
+ _displayName = getText (configFile >> "CfgMagazines" >> _x >> "displayName");
+ _picture = getText (configFile >> "CfgMagazines" >> _x >> "picture");
+ _actions = [_actions, _displayName, _picture, _x] call EFUNC(interaction,addSelectableItem);
+ };
+} forEach _unitMagazines;
[
- _actions,
- {
- _data = _this;
- call EFUNC(interaction,hideMenu);
- if (isNil "_data") exitWith {};
- _data set [2, [_data select 2] call EFUNC(common,toNumber)];
- [(_data select 2), _data, {(_this select 0) call FUNC(magazineRepackCallback)}, {}, (localize "STR_ACE_MagazineRepack_RepackingMagazine")] call EFUNC(common,progressBar);
- [ACE_player] call EFUNC(common,goKneeling);
- },
- {
- call EFUNC(interaction,hideMenu);
- if !(profileNamespace getVariable [QGVAR(AutoCloseMenu), false]) then {"Default" call EFUNC(interaction,openMenuSelf)};
- }
+_actions,
+{ [ACE_player, _this] call FUNC(startRepackingMagazine); },
+{
+ call EFUNC(interaction,hideMenu);
+ if !(profileNamespace getVariable [QGVAR(AutoCloseMenu), false]) then {"Default" call EFUNC(interaction,openMenuSelf)};
+}
] call EFUNC(interaction,openSelectMenu);
diff --git a/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf b/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf
new file mode 100644
index 0000000000..9df248bd6c
--- /dev/null
+++ b/addons/magazinerepack/functions/fnc_simulateRepackEvents.sqf
@@ -0,0 +1,52 @@
+#include "script_component.hpp"
+
+private ["_fullMagazineCount", "_magazines", "_newMag", "_time", "_events", "_swapAmmo", "_ammoSwaped", "_lowIndex", "_highIndex", "_ammoToTransfer", "_ammoAvailable", "_ammoNeeded"];
+
+PARAMS_2(_magazineClassname,_arrayOfAmmoCounts);
+
+// Calculate actual ammo to transfer during repack
+_fullMagazineCount = getNumber (configfile >> "CfgMagazines" >> _magazineClassname >> "count");
+
+// Sort Ascending - Don't modify orginal
+_arrayOfAmmoCounts = (+_arrayOfAmmoCounts) call BIS_fnc_sortNum;
+
+_newMag = {
+ _time = _time + GVAR(TimePerMagazine);
+ _events pushBack [_time, 1, +_arrayOfAmmoCounts];
+};
+_swapAmmo = {
+ for "_swapProgress" from 1 to _ammoSwaped do {
+ _time = _time + GVAR(TimePerAmmo);
+ _arrayOfAmmoCounts set [_lowIndex, ((_arrayOfAmmoCounts select _lowIndex) - 1)];
+ _arrayOfAmmoCounts set [_highIndex, ((_arrayOfAmmoCounts select _highIndex) + 1)];
+ _events pushBack [_time, 0, +_arrayOfAmmoCounts];
+ };
+};
+
+_lowIndex = 0;
+_highIndex = (count _arrayOfAmmoCounts) - 1;
+_ammoToTransfer = 0;
+_ammoAvailable = 0;
+
+_time = 0;
+_events = [];
+
+while {_lowIndex < _highIndex} do {
+ _ammoNeeded = _fullMagazineCount - (_arrayOfAmmoCounts select _highIndex);
+ _ammoAvailable = _arrayOfAmmoCounts select _lowIndex;
+
+ if (_ammoAvailable == 0) then {
+ _lowIndex = _lowIndex + 1;
+ call _newMag;
+ } else {
+ if (_ammoNeeded == 0) then {
+ _highIndex = _highIndex - 1;
+ call _newMag;
+ } else {
+ _ammoSwaped = _ammoAvailable min _ammoNeeded;
+ call _swapAmmo;
+ };
+ };
+};
+
+_events
diff --git a/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf
new file mode 100644
index 0000000000..8e5075e17e
--- /dev/null
+++ b/addons/magazinerepack/functions/fnc_startRepackingMagazine.sqf
@@ -0,0 +1,39 @@
+// by commy2, esteldunedain
+#include "script_component.hpp"
+
+private ["_unit", "_magazines", "_ammos", "_repackTime", "_magazine", "_ammo", "_count", "_index", "_i", "_j", "_ammoToTransfer", "_ammoAvailable", "_ammoNeeded"];
+
+PARAMS_2(_unit,_magazineClassname);
+if (isNil "_magazineClassname" || {_magazineClassname == ""}) exitWith {ERROR("Bad Mag Classname");};
+
+[_unit] call EFUNC(common,goKneeling);
+call EFUNC(interaction,hideMenu);
+
+_startingAmmoCounts = [];
+{
+ EXPLODE_4_PVT(_x,_xClassname,_xCount,_xLoaded,_xType);
+ if (_xClassname == _magazineClassname) then {
+ if (_xLoaded) then {
+ //Try to Remove from weapon and add to inventory, otherwise ignore
+ if (_unit canAdd _magazineClassname) then {
+ switch (_xType) do {
+ case (1): {_unit removePrimaryWeaponItem _magazineClassname;};
+ case (2): {_unit removeHandgunItem _magazineClassname;};
+ case (4): {_unit removeSecondaryWeaponItem _magazineClassname;};
+ default {ERROR("Loaded Location Invalid");};
+ };
+ _unit addMagazine [_magazineClassname, _xCount];
+ _startingAmmoCounts pushBack _xCount;
+ };
+ } else {
+ _startingAmmoCounts pushBack _xCount;
+ };
+ };
+} forEach (magazinesAmmoFull _unit);
+
+if ((count _startingAmmoCounts) == 0) exitwith {ERROR("No Mags");};
+
+_simEvents = [_magazineClassname, _startingAmmoCounts] call FUNC(simulateRepackEvents);
+_totalTime = (_simEvents select ((count _simEvents) - 1) select 0);
+
+[_totalTime, [_magazineClassname, _startingAmmoCounts, _simEvents], {hint "done"}, {hint "fail"}, (localize "STR_ACE_MagazineRepack_RepackingMagazine"), {_this call FUNC(magazineRepackProgress)}] call EFUNC(common,progressBar);
diff --git a/addons/magazinerepack/script_component.hpp b/addons/magazinerepack/script_component.hpp
index 7b390f7126..15563f0fe8 100644
--- a/addons/magazinerepack/script_component.hpp
+++ b/addons/magazinerepack/script_component.hpp
@@ -1,3 +1,5 @@
+#define DEBUG_MODE_FULL
+
#define COMPONENT magazinerepack
#include "\z\ace\addons\main\script_mod.hpp"
diff --git a/addons/magazinerepack/sounds/magrepack_finished.wav b/addons/magazinerepack/sounds/magrepack_finished.wav
new file mode 100644
index 0000000000..ab73615a55
Binary files /dev/null and b/addons/magazinerepack/sounds/magrepack_finished.wav differ
diff --git a/addons/magazinerepack/sounds/magrepack_single.wav b/addons/magazinerepack/sounds/magrepack_single.wav
new file mode 100644
index 0000000000..5d94e215fd
Binary files /dev/null and b/addons/magazinerepack/sounds/magrepack_single.wav differ