diff --git a/README.md b/README.md
index 2fcce1d1fd..74e32e1fac 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
-
+
diff --git a/VERSION b/VERSION
index 69499073cf..d87a10b470 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-3.12.5.40
+3.12.6.43
diff --git a/addons/arsenal/Cfg3DEN.hpp b/addons/arsenal/Cfg3DEN.hpp
index 8e79b726b4..8b40f77bfe 100644
--- a/addons/arsenal/Cfg3DEN.hpp
+++ b/addons/arsenal/Cfg3DEN.hpp
@@ -55,7 +55,7 @@ class Cfg3DEN {
};
class Category: ctrlToolboxPictureKeepAspect {
idc = IDC_ATTRIBUTE_CATEGORY;
- onToolBoxSelChanged = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems));
+ onToolBoxSelChanged = QUOTE([ARR_2(ctrlParentControlsGroup (_this select 0), _this select 1)] call FUNC(attributeCategory));
x = QUOTE(5 * ATTRIBUTE_W);
y = QUOTE(15 * ATTRIBUTE_H);
w = QUOTE(125 * ATTRIBUTE_W);
@@ -129,7 +129,14 @@ class Cfg3DEN {
};
class SearchButton: ctrlButtonPicture {
idc = IDC_ATTRIBUTE_SEARCH_BUTTON;
- onButtonClick = QUOTE(((ctrlParentControlsGroup (_this select 0)) controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR) ctrlSetText ''; [ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems));
+ onButtonClick = QUOTE( \
+ params ['_searchButton']; \
+ private _controlsGroup = ctrlParentControlsGroup _searchButton; \
+ private _searchBar = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_SEARCHBAR; \
+ _searchBar ctrlSetText ''; \
+ ctrlSetFocus _searchBar; \
+ [_controlsGroup] call FUNC(attributeAddItems); \
+ );
text = "\a3\Ui_f\data\GUI\RscCommon\RscButtonSearch\search_start_ca.paa";
x = QUOTE(5 * ATTRIBUTE_W);
y = QUOTE(101.83 * ATTRIBUTE_H);
@@ -140,9 +147,16 @@ class Cfg3DEN {
class SearchBar: ctrlEdit {
idc = IDC_ATTRIBUTE_SEARCHBAR;
onKeyUp = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddItems));
+ onMouseButtonClick = QUOTE( \
+ params [ARR_2('_searchBar','_button')]; \
+ if (_button != 1) exitWith {}; \
+ _searchBar ctrlSetText ''; \
+ ctrlSetFocus _searchBar; \
+ [ctrlParentControlsGroup _searchBar] call FUNC(attributeAddItems); \
+ );
x = QUOTE(11 * ATTRIBUTE_W);
y = QUOTE(101.83 * ATTRIBUTE_H);
- w = QUOTE(55 * ATTRIBUTE_W);
+ w = QUOTE(40 * ATTRIBUTE_W);
h = QUOTE(5 * ATTRIBUTE_H);
};
class ClearButton: ctrlButton {
@@ -162,6 +176,27 @@ class Cfg3DEN {
tooltip = CSTRING(AttributeExport_Tooltip);
x = QUOTE(79 * ATTRIBUTE_W);
};
+ class ImportButton: ClearButton {
+ idc = IDC_ATTRIBUTE_IMPORT_BUTTON;
+ onButtonClick = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeImport));
+ text = CSTRING(buttonImportText);
+ tooltip = CSTRING(AttributeImport_Tooltip);
+ x = QUOTE(53 * ATTRIBUTE_W);
+ };
+ class AddCompatible: ctrlButton {
+ idc = IDC_ATTRIBUTE_ADD_COMPATIBLE;
+ style = ST_CENTER;
+ onButtonClick = QUOTE([ctrlParentControlsGroup (_this select 0)] call FUNC(attributeAddCompatible));
+ text = CSTRING(AttributeAddCompatible_DisplayName);
+ tooltip = CSTRING(AttributeAddCompatible_Tooltip);
+ font = "RobotoCondensedLight";
+ x = QUOTE(98.75 * ATTRIBUTE_W);
+ y = QUOTE(10.5 * ATTRIBUTE_H);
+ w = QUOTE(31.25 * ATTRIBUTE_W);
+ h = QUOTE(4 * ATTRIBUTE_H);
+ sizeEx = QUOTE(4 * ATTRIBUTE_H);
+ colorBackground[] = {0, 0, 0, 0.5};
+ };
};
};
};
diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp
index 3e64d3654e..656fc5b1d5 100644
--- a/addons/arsenal/XEH_PREP.hpp
+++ b/addons/arsenal/XEH_PREP.hpp
@@ -2,9 +2,12 @@ PREP(addDefaultLoadout);
PREP(addListBoxItem);
PREP(addStat);
PREP(addVirtualItems);
+PREP(attributeAddCompatible);
PREP(attributeAddItems);
+PREP(attributeCategory);
PREP(attributeClear);
PREP(attributeDblClick);
+PREP(attributeImport);
PREP(attributeInit);
PREP(attributeKeyDown);
PREP(attributeLoad);
diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp
index 9210ed9b2e..35d2edc461 100644
--- a/addons/arsenal/defines.hpp
+++ b/addons/arsenal/defines.hpp
@@ -162,6 +162,8 @@
#define IDC_ATTRIBUTE_SEARCHBAR 8106
#define IDC_ATTRIBUTE_CLEAR_BUTTON 8107
#define IDC_ATTRIBUTE_EXPORT_BUTTON 8108
+#define IDC_ATTRIBUTE_IMPORT_BUTTON 8109
+#define IDC_ATTRIBUTE_ADD_COMPATIBLE 8110
#define SYMBOL_ITEM_NONE "−"
#define SYMBOL_ITEM_REMOVE "×"
diff --git a/addons/arsenal/functions/fnc_attributeAddCompatible.sqf b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf
new file mode 100644
index 0000000000..4f84f9624c
--- /dev/null
+++ b/addons/arsenal/functions/fnc_attributeAddCompatible.sqf
@@ -0,0 +1,75 @@
+#include "script_component.hpp"
+#include "..\defines.hpp"
+/*
+ * Author: mharis001
+ * Adds compatible attachments or magazines for all weapons in 3DEN attribute.
+ *
+ * Arguments:
+ * 0: Attribute controls group
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [CONTROL] call ace_arsenal_fnc_attributeAddCompatible
+ *
+ * Public: No
+ */
+
+params ["_controlsGroup"];
+
+private _category = lbCurSel (_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY);
+
+// Exit if selected category is not attachments or magazines
+if !(_category in [4, 5, 6, 7, 8]) exitWith {};
+
+private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]);
+private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]];
+_attributeValue params ["_attributeItems"];
+
+// Get list of all weapons in attribute items
+(_configItems select 0) params ["_primaryWeapons", "_secondaryWeapons", "_handgunWeapons"];
+private _attributeWeapons = _attributeItems select {_x in _primaryWeapons || {_x in _secondaryWeapons} || {_x in _handgunWeapons}};
+
+// Add compatible attachments or magazines to attribute
+private _cfgWeapons = configFile >> "CfgWeapons";
+private _itemsToAdd = [];
+
+if (_category == 8) then {
+ private _magazineGroups = uiNamespace getVariable QGVAR(magazineGroups);
+ private _cfgMagazines = configFile >> "CfgMagazines";
+
+ {
+ private _weaponConfig = _cfgWeapons >> _x;
+
+ {
+ private _muzzleConfig = if (_x == "this") then {_weaponConfig} else {_weaponConfig >> _x};
+
+ // Only add existent magazines and ensure correct classname case
+ private _magazines = getArray (_muzzleConfig >> "magazines") select {isClass (_cfgMagazines >> _x)};
+ _magazines = _magazines apply {configName (_cfgMagazines >> _x)};
+ _itemsToAdd append _magazines;
+
+ {
+ _itemsToAdd append ([_magazineGroups, toLower _x] call CBA_fnc_hashGet);
+ } forEach getArray (_muzzleConfig >> "magazineWell");
+ } forEach getArray (_weaponConfig >> "muzzles");
+ } forEach _attributeWeapons;
+} else {
+ private _attachmentCategory = _category - 4;
+ private _filter = ["optic", "pointer", "muzzle", "bipod"] select _attachmentCategory;
+
+ {
+ _itemsToAdd append ([_x, _filter] call CBA_fnc_compatibleItems);
+ } forEach _attributeWeapons;
+
+ // Only add items with scope of 2 and ensure correct classname case
+ _itemsToAdd = _itemsToAdd select {getNumber (_cfgWeapons >> _x >> "scope") == 2};
+ _itemsToAdd = _itemsToAdd apply {configName (_cfgWeapons >> _x)};
+};
+
+_attributeItems append _itemsToAdd;
+_attributeValue set [0, _attributeItems arrayIntersect _attributeItems];
+
+// Refresh the list for new items
+[_controlsGroup] call FUNC(attributeAddItems);
diff --git a/addons/arsenal/functions/fnc_attributeCategory.sqf b/addons/arsenal/functions/fnc_attributeCategory.sqf
new file mode 100644
index 0000000000..e0c0468f8a
--- /dev/null
+++ b/addons/arsenal/functions/fnc_attributeCategory.sqf
@@ -0,0 +1,32 @@
+#include "script_component.hpp"
+#include "..\defines.hpp"
+/*
+ * Author: mharis001
+ * Handles changing the category in 3DEN attribute.
+ *
+ * Arguments:
+ * 0: Attribute controls group
+ * 1: Category
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [CONTROL, 0] call ace_arsenal_fnc_attributeCategory
+ *
+ * Public: No
+ */
+
+params ["_controlsGroup", "_category"];
+
+// Store selected category
+uiNamespace setVariable [QGVAR(attributeCategory), _category];
+
+// Show add compatible items button when category is attachments or magazines
+private _compatibleButton = _controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_ADD_COMPATIBLE;
+private _enable = _category in [4, 5, 6, 7, 8];
+_compatibleButton ctrlEnable _enable;
+_compatibleButton ctrlShow _enable;
+
+// Refresh the list for selected category
+[_controlsGroup] call FUNC(attributeAddItems);
diff --git a/addons/arsenal/functions/fnc_attributeImport.sqf b/addons/arsenal/functions/fnc_attributeImport.sqf
new file mode 100644
index 0000000000..ec56df4b56
--- /dev/null
+++ b/addons/arsenal/functions/fnc_attributeImport.sqf
@@ -0,0 +1,49 @@
+#include "script_component.hpp"
+/*
+ * Author: mharis001
+ * Handles importing items list from clipboard into 3DEN attribute.
+ *
+ * Arguments:
+ * 0: Attribute controls group
+ *
+ * Return Value:
+ * None
+ *
+ * Example:
+ * [CONTROL] call ace_arsenal_fnc_attributeImport
+ *
+ * Public: No
+ */
+
+params ["_controlsGroup"];
+
+private _importList = call compile copyFromClipboard;
+
+// Verify import list is in correct format
+if (isNil "_importList" || {!(_importList isEqualType [])} || {!(_importList isEqualTypeAll "")}) exitWith {
+ playSound ["3DEN_notificationWarning", true];
+};
+
+// Ensure imported items are in scanned config array and classname case is correct
+private _configItems = +(uiNamespace getVariable [QGVAR(configItems), []]);
+private _configItemsFlat = _configItems select [2, 16];
+_configItemsFlat append (_configItems select 0);
+_configItemsFlat append (_configItems select 1);
+
+private _filteredList = [];
+
+{
+ private _item = _x;
+ {
+ private _index = _x findIf {_x == _item};
+ if (_index > -1) then {
+ _filteredList pushBackUnique (_x select _index);
+ };
+ } forEach _configItemsFlat;
+} forEach _importList;
+
+private _attributeValue = uiNamespace getVariable [QGVAR(attributeValue), [[], 0]];
+_attributeValue set [0, _filteredList];
+
+// Refresh the list for new items
+[_controlsGroup] call FUNC(attributeAddItems);
diff --git a/addons/arsenal/functions/fnc_attributeLoad.sqf b/addons/arsenal/functions/fnc_attributeLoad.sqf
index 439ec2ff36..355d5e113a 100644
--- a/addons/arsenal/functions/fnc_attributeLoad.sqf
+++ b/addons/arsenal/functions/fnc_attributeLoad.sqf
@@ -34,4 +34,8 @@ if (_value select 1 > 0) then {
(_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_LIST_RIGHT) ctrlSetText SYMBOL_ITEM_REMOVE;
};
-[_controlsGroup] call FUNC(attributeAddItems);
+// Trigger category selection for last selected category to populate list
+private _category = uiNamespace getVariable [QGVAR(attributeCategory), 0];
+(_controlsGroup controlsGroupCtrl IDC_ATTRIBUTE_CATEGORY) lbSetCurSel _category;
+
+[_controlsGroup, _category] call FUNC(attributeCategory);
diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf
index fdb73c72ef..2bddbf4c5c 100644
--- a/addons/arsenal/functions/fnc_scanConfig.sqf
+++ b/addons/arsenal/functions/fnc_scanConfig.sqf
@@ -57,7 +57,7 @@ private _configCfgWeapons = configFile >> "CfgWeapons"; //Save this lookup in va
case (_itemInfoType == TYPE_HEADGEAR): {
(_cargo select 3) pushBackUnique _className;
};
- /* Uniform */\
+ /* Uniform */
case (_itemInfoType == TYPE_UNIFORM): {
(_cargo select 4) pushBackUnique _className;
};
diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml
index 564770cb58..a3bd8baa04 100644
--- a/addons/arsenal/stringtable.xml
+++ b/addons/arsenal/stringtable.xml
@@ -103,6 +103,7 @@
[Shift+Click to save to mission defaults]
[Shift + クリック] でミッション標準として保存します
+ Shift + Klik aby zapisac jako domyślne dla misji
Rename
@@ -824,7 +825,7 @@
Whitelist
- Biała lista
+ Biała lista (lista wybranych)
Lista blanca
Whitelist
Seznam povolených
@@ -842,7 +843,7 @@
Blacklist
禁止リスト
Lista Nera
- Czarna lista
+ Czarna lista (lista wykluczeń)
Items
@@ -866,6 +867,18 @@
Esporta l'attuale lista di elementi come un array, per essere usati negli script
Eksportuj obecną listę przedmiotów jako tablicę do wykorzystania w skryptach
+
+ Import items list array from clipboard (should be the same format as export)
+ Zaimportuj listę przedmiotów ze schowka (lista musi być w tym samym formacie jak przy exporcie)
+
+
+ Add Compatible Items
+ Dodaj kompatybilne przedmioty
+
+
+ Will automatically add compatible attachments or magazines (based on selected category) for all weapons in current items list
+ Automatycznie doda kompatybilne dodatki oraz magazynki (odpowiednio do każdej kategorii) dla wszystkich broni na liście
+
Time to live
Durée de vie
diff --git a/addons/dagr/functions/fnc_menuInit.sqf b/addons/dagr/functions/fnc_menuInit.sqf
index 0425f1f4d2..c535ac1349 100644
--- a/addons/dagr/functions/fnc_menuInit.sqf
+++ b/addons/dagr/functions/fnc_menuInit.sqf
@@ -347,7 +347,7 @@ GVAR(menuRun) = true;
GVAR(digit4) = floor (GVAR(wp0) / 10000 - GVAR(digit3) * 10 - GVAR(digit2) * 100 - GVAR(digit1) * 1000);
GVAR(digit5) = floor (GVAR(wp0) / 1000 - GVAR(digit4) * 10 - GVAR(digit3) * 100 - GVAR(digit2) * 1000 - GVAR(digit1) * 10000);
GVAR(digit6) = floor (GVAR(wp0) / 100 - GVAR(digit5) * 10 - GVAR(digit4) * 100 - GVAR(digit3) * 1000 - GVAR(digit2) * 10000 - GVAR(digit1) * 100000);
- GVAR(digit7) = floor (GVAR(wp0) / 10- GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
+ GVAR(digit7) = floor (GVAR(wp0) / 10 - GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
GVAR(digit8) = floor (GVAR(wp0) - GVAR(digit7) * 10 - GVAR(digit6) * 100 - GVAR(digit5) * 1000 - GVAR(digit4) * 10000 - GVAR(digit3) * 100000 - GVAR(digit2) * 1000000 - GVAR(digit1) * 10000000);
};
case 1: {
@@ -357,7 +357,7 @@ GVAR(menuRun) = true;
GVAR(digit4) = floor (GVAR(wp1) / 10000 - GVAR(digit3) * 10 - GVAR(digit2) * 100 - GVAR(digit1) * 1000);
GVAR(digit5) = floor (GVAR(wp1) / 1000 - GVAR(digit4) * 10 - GVAR(digit3) * 100 - GVAR(digit2) * 1000 - GVAR(digit1) * 10000);
GVAR(digit6) = floor (GVAR(wp1) / 100 - GVAR(digit5) * 10 - GVAR(digit4) * 100 - GVAR(digit3) * 1000 - GVAR(digit2) * 10000 - GVAR(digit1) * 100000);
- GVAR(digit7) = floor (GVAR(wp1) / 10- GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
+ GVAR(digit7) = floor (GVAR(wp1) / 10 - GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
GVAR(digit8) = floor (GVAR(wp1) - GVAR(digit7) * 10 - GVAR(digit6) * 100 - GVAR(digit5) * 1000 - GVAR(digit4) * 10000 - GVAR(digit3) * 100000 - GVAR(digit2) * 1000000 - GVAR(digit1) * 10000000);
};
case 2: {
@@ -367,7 +367,7 @@ GVAR(menuRun) = true;
GVAR(digit4) = floor (GVAR(wp2) / 10000 - GVAR(digit3) * 10 - GVAR(digit2) * 100 - GVAR(digit1) * 1000);
GVAR(digit5) = floor (GVAR(wp2) / 1000 - GVAR(digit4) * 10 - GVAR(digit3) * 100 - GVAR(digit2) * 1000 - GVAR(digit1) * 10000);
GVAR(digit6) = floor (GVAR(wp2) / 100 - GVAR(digit5) * 10 - GVAR(digit4) * 100 - GVAR(digit3) * 1000 - GVAR(digit2) * 10000 - GVAR(digit1) * 100000);
- GVAR(digit7) = floor (GVAR(wp2) / 10- GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
+ GVAR(digit7) = floor (GVAR(wp2) / 10 - GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
GVAR(digit8) = floor (GVAR(wp2) - GVAR(digit7) * 10 - GVAR(digit6) * 100 - GVAR(digit5) * 1000 - GVAR(digit4) * 10000 - GVAR(digit3) * 100000 - GVAR(digit2) * 1000000 - GVAR(digit1) * 10000000);
};
case 3: {
@@ -377,7 +377,7 @@ GVAR(menuRun) = true;
GVAR(digit4) = floor (GVAR(wp3) / 10000 - GVAR(digit3) * 10 - GVAR(digit2) * 100 - GVAR(digit1) * 1000);
GVAR(digit5) = floor (GVAR(wp3) / 1000 - GVAR(digit4) * 10 - GVAR(digit3) * 100 - GVAR(digit2) * 1000 - GVAR(digit1) * 10000);
GVAR(digit6) = floor (GVAR(wp3) / 100 - GVAR(digit5) * 10 - GVAR(digit4) * 100 - GVAR(digit3) * 1000 - GVAR(digit2) * 10000 - GVAR(digit1) * 100000);
- GVAR(digit7) = floor (GVAR(wp3) / 10- GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
+ GVAR(digit7) = floor (GVAR(wp3) / 10 - GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
GVAR(digit8) = floor (GVAR(wp3) - GVAR(digit7) * 10 - GVAR(digit6) * 100 - GVAR(digit5) * 1000 - GVAR(digit4) * 10000 - GVAR(digit3) * 100000 - GVAR(digit2) * 1000000 - GVAR(digit1) * 10000000);
};
case 4: {
@@ -387,7 +387,7 @@ GVAR(menuRun) = true;
GVAR(digit4) = floor (GVAR(wp4) / 10000 - GVAR(digit3) * 10 - GVAR(digit2) * 100 - GVAR(digit1) * 1000);
GVAR(digit5) = floor (GVAR(wp4) / 1000 - GVAR(digit4) * 10 - GVAR(digit3) * 100 - GVAR(digit2) * 1000 - GVAR(digit1) * 10000);
GVAR(digit6) = floor (GVAR(wp4) / 100 - GVAR(digit5) * 10 - GVAR(digit4) * 100 - GVAR(digit3) * 1000 - GVAR(digit2) * 10000 - GVAR(digit1) * 100000);
- GVAR(digit7) = floor (GVAR(wp4) / 10- GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
+ GVAR(digit7) = floor (GVAR(wp4) / 10 - GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
GVAR(digit8) = floor (GVAR(wp4) - GVAR(digit7) * 10 - GVAR(digit6) * 100 - GVAR(digit5) * 1000 - GVAR(digit4) * 10000 - GVAR(digit3) * 100000 - GVAR(digit2) * 1000000 - GVAR(digit1) * 10000000);
};
};
@@ -457,7 +457,7 @@ GVAR(menuRun) = true;
GVAR(digit4) = floor(_gridVector / 10000 - GVAR(digit3) * 10 - GVAR(digit2) * 100 - GVAR(digit1) * 1000);
GVAR(digit5) = floor(_gridVector / 1000 - GVAR(digit4) * 10 - GVAR(digit3) * 100 - GVAR(digit2) * 1000 - GVAR(digit1) * 10000);
GVAR(digit6) = floor(_gridVector / 100 - GVAR(digit5) * 10 - GVAR(digit4) * 100 - GVAR(digit3) * 1000 - GVAR(digit2) * 10000 - GVAR(digit1) * 100000);
- GVAR(digit7) = floor(_gridVector / 10- GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
+ GVAR(digit7) = floor(_gridVector / 10 - GVAR(digit6) * 10 - GVAR(digit5) * 100 - GVAR(digit4) * 1000 - GVAR(digit3) * 10000 - GVAR(digit2) * 100000 - GVAR(digit1) * 1000000);
GVAR(digit8) = floor(_gridVector - GVAR(digit7) * 10 - GVAR(digit6) * 100 - GVAR(digit5) * 1000 - GVAR(digit4) * 10000 - GVAR(digit3) * 100000 - GVAR(digit2) * 1000000 - GVAR(digit1) * 10000000);
};
if (GVAR(F3)) then {
diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml
index 4401196769..71a2f17038 100644
--- a/addons/fastroping/stringtable.xml
+++ b/addons/fastroping/stringtable.xml
@@ -148,66 +148,79 @@
Deploy 12m ropes
Déployer les cordes 12m
12m ロープを展開
+ Wysuń linę o długości 12 m.
Deploy 15m ropes
Déployer les cordes 15m
15m ロープを展開
+ Wysuń linę o długości 15 m.
Deploy 18m ropes
Déployer les cordes 18m
18m ロープを展開
+ Wysuń linę o długości 18 m.
Deploy 27m ropes
Déployer les cordes 27m
27m ロープを展開
+ Wysuń linę o długości 27 m.
Deploy 36m ropes
Déployer les cordes 36m
36m ロープを展開
+ Wysuń linę o długości 36 m.
[ACE] Ropes Supply crate
[ACE] Caisse de Cordes
[ACE] ロープ収納箱
+ Skrzynia z linami ACE
Used to do deploy ropes from a compatibile helicopter
Utilisé pour déployer des cordes depuis un hélicoptère compatible
対応するヘリコプターからロープを展開する為に使用されます
+ Używane do opuszczania lin z kompatybilnych smigłowców
Rope 12.2 meters
Corde 12.2 mètres
ロープ (12.2 メートル)
+ Lina, długość 12,2 m.
Rope 15.2 meters
Corde 15.2 mètres
ロープ (15.2 メートル)
+ Lina, długość 15,2 m.
Rope 18.3 meters
Corde 18.3 mètres
ロープ (18.3 メートル)
+ Lina, długość 18,3 m.
Rope 27.4 meters
Corde 27.4 mètres
ロープ (27.4 メートル)
+ Lina, długość 27,4 m.
Rope 36.6 meters
Corde 36.6 mètres
ロープ (36.6 メートル)
+ Lina, długość 36,6 m.
Require rope item to deploy
Exiger une corde pour déployer
展開にはロープ アイテムを必須に
+ Wymaga przedmiotu typu lina
diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf
index a5aee2d18e..4921bd42d9 100644
--- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf
+++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf
@@ -80,14 +80,14 @@ GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[10,10,0,0,
if !(ACE_player getVariable ["ACE_isUnconscious", false]) then {
if (_average > 0.30 * _gBlackOut) then {
private _strength = ((_average - 0.30 * _gBlackOut) / (0.70 * _gBlackOut)) max 0;
- GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[2*(1-_strength),2*(1-_strength),0,0,0,0.1,0.5]];
+ GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[2 * (1 - _strength),2 * (1 - _strength),0,0,0,0.1,0.5]];
addCamShake [_strength, 1, 15];
} else {
private _gRedOut = MINVIRTUALG / _classCoef;
if (_average < -0.30 * _gRedOut) then {
private _strength = ((abs _average - 0.30 * _gRedOut) / (0.70 * _gRedOut)) max 0;
- GVAR(GForces_CC) ppEffectAdjust [1,1,0,[1,0.2,0.2,1],[0,0,0,0],[1,1,1,1],[2*(1-_strength),2*(1-_strength),0,0,0,0.1,0.5]];
+ GVAR(GForces_CC) ppEffectAdjust [1,1,0,[1,0.2,0.2,1],[0,0,0,0],[1,1,1,1],[2 * (1 - _strength),2 * ( 1 -_strength),0,0,0,0.1,0.5]];
addCamShake [_strength / 1.5, 1, 15];
};
};
diff --git a/addons/grenades/models/ACE_M84.p3d b/addons/grenades/models/ACE_M84.p3d
index e24ff37880..f3e4119873 100644
Binary files a/addons/grenades/models/ACE_M84.p3d and b/addons/grenades/models/ACE_M84.p3d differ
diff --git a/addons/grenades/models/ACE_M84_thrown.p3d b/addons/grenades/models/ACE_M84_thrown.p3d
index 0b206cfada..20f322c643 100644
Binary files a/addons/grenades/models/ACE_M84_thrown.p3d and b/addons/grenades/models/ACE_M84_thrown.p3d differ
diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf
index 7292c86f85..954dc4dee1 100644
--- a/addons/hearing/functions/fnc_putInEarplugs.sqf
+++ b/addons/hearing/functions/fnc_putInEarplugs.sqf
@@ -29,7 +29,7 @@ _player setVariable ["ACE_hasEarPlugsIn", true, true];
//Force an immediate fast volume update:
[[true]] call FUNC(updateVolume);
-/*// No Earplugs in inventory, telling user
-[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured);*/
+// No Earplugs in inventory, telling user
+//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured);
[] call FUNC(updateHearingProtection);
diff --git a/addons/interaction/ACE_ZeusActions.hpp b/addons/interaction/ACE_ZeusActions.hpp
index bdadfa5e63..9fad6c819a 100644
--- a/addons/interaction/ACE_ZeusActions.hpp
+++ b/addons/interaction/ACE_ZeusActions.hpp
@@ -54,7 +54,7 @@ class ACE_ZeusActions {
displayName = "$STR_repair";
icon = "\A3\ui_f\data\igui\cfg\actions\repair_ca.paa";
condition = QUOTE(ZEUS_ACTION_CONDITION && {-1 < (curatorSelected select 0) findIf {_x isKindOf 'AllVehicles' && {!(_x isKindOf 'Man')}}});
- statement = QUOTE({if (_x isKindOf 'AllVehicles' && {!(_x isKindOf 'Man')}) then {_x setDamage 0}} forEach (curatorSelected select 0));
+ statement = QUOTE(call FUNC(repair_Statement));
};
};
diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf
index b47cf6628d..dbc37e2bb6 100644
--- a/addons/interaction/XEH_preInit.sqf
+++ b/addons/interaction/XEH_preInit.sqf
@@ -6,4 +6,11 @@ PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;
+DFUNC(repair_Statement) = { // moved from config because of build problems
+ TRACE_1("repair_Statement",_this);
+ {
+ if (_x isKindOf 'AllVehicles' && {!(_x isKindOf 'Man')}) then { _x setDamage 0; };
+ } forEach (curatorSelected select 0)
+};
+
ADDON = true;
diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp
index f046b3d4ef..fe84527032 100644
--- a/addons/main/script_version.hpp
+++ b/addons/main/script_version.hpp
@@ -1,4 +1,4 @@
#define MAJOR 3
#define MINOR 12
-#define PATCHLVL 5
-#define BUILD 40
+#define PATCHLVL 6
+#define BUILD 43
diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml
index a2615f0410..4c1e4d1c3b 100644
--- a/addons/markers/stringtable.xml
+++ b/addons/markers/stringtable.xml
@@ -101,6 +101,7 @@
Creator
Ersteller
設置者
+ Twórca
diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml
index 65e2719f5b..5979939451 100644
--- a/addons/medical/stringtable.xml
+++ b/addons/medical/stringtable.xml
@@ -1653,7 +1653,7 @@
Kochsalzlösung (500ml)
0,9%-os sósvíz-infúzió (500ml)
Soluzione salina EV (500ml)
- Soro IV (1000ml)
+ Soro IV (500ml)
Fyziologický roztok (500ml)
生理食塩水 IV (500ml)
생리식염수 IV (500ml)
@@ -1669,7 +1669,7 @@
Kochsalzlösung (250ml)
0,9%-os sósvíz-infúzió (250ml)
Soluzione salina EV (250ml)
- Soro IV (1000ml)
+ Soro IV (250ml)
Fyziologický roztok (250ml)
生理食塩水 IV (250ml)
생리식염수 IV (250ml)
@@ -3180,10 +3180,12 @@
Selections (3d)
@@ -5700,14 +5702,17 @@
Convert vanilla items
標準アイテムを変換
+ Skonwertuj przedmioty z Army3 (vanilia) na przedmioty medyczne ACE3
Enables or disables whether vanilla medical items are converted to ACE medical items or just removed
有効化すると標準の治療アイテムを ACE 治療アイテムへ変換し、無効化すると削除します。
+ Decyduje czy oryginalne przedmioty medyczne z Army 3 mają być skonwertowane na przedmioty medyczne ACE3 czy usunięte
Just remove vanilla medical
標準の治療アイテムを削除
+ Usuń przedmioty z Army 3 (vanilia)
diff --git a/addons/rearm/ACE_ZeusActions.hpp b/addons/rearm/ACE_ZeusActions.hpp
index 89fd4a6537..2d05e34a4c 100644
--- a/addons/rearm/ACE_ZeusActions.hpp
+++ b/addons/rearm/ACE_ZeusActions.hpp
@@ -4,13 +4,7 @@ class ACE_ZeusActions {
displayName = CSTRING(Rearm);
icon = QPATHTOF(ui\icon_rearm_interact.paa);
condition = QUOTE(ZEUS_ACTION_CONDITION && {-1 < (curatorSelected select 0) findIf {_x isKindOf 'AllVehicles' && {!(_x isKindOf 'Man')}}});
- statement = QUOTE( \
- { \
- if (_x isKindOf 'AllVehicles' && {!(_x isKindOf 'Man')}) then { \
- [ARR_2(objNull,_x)] call ace_rearm_fnc_rearmEntireVehicleSuccess; \
- }; \
- } forEach (curatorSelected select 0); \
- );
+ statement = QUOTE(call FUNC(rearm_statement));
};
};
};
diff --git a/addons/rearm/XEH_preInit.sqf b/addons/rearm/XEH_preInit.sqf
index 9361d05015..10156a7d1c 100644
--- a/addons/rearm/XEH_preInit.sqf
+++ b/addons/rearm/XEH_preInit.sqf
@@ -8,4 +8,13 @@ PREP_RECOMPILE_END;
#include "initSettings.sqf"
+DFUNC(rearm_statement) = { // moved from config because of build problems
+ TRACE_1("rearm_statement",_this);
+ {
+ if (_x isKindOf 'AllVehicles' && {!(_x isKindOf 'Man')}) then {
+ [objNull, _x] call FUNC(rearmEntireVehicleSuccess);
+ };
+ } forEach (curatorSelected select 0);
+};
+
ADDON = true;
diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp
index 7f0255d2a5..a41c2db501 100644
--- a/addons/repair/CfgVehicles.hpp
+++ b/addons/repair/CfgVehicles.hpp
@@ -456,8 +456,7 @@ class CfgVehicles {
GVAR(hitpointPositions)[] = {{"HitTurret", {0,-2,0}}};
};
- class Car_F;
- class Offroad_01_base_F: Car_F {};
+ class Offroad_01_base_F;
class Offroad_01_repair_base_F: Offroad_01_base_F {
GVAR(canRepair) = 1;
transportRepair = 0;
@@ -483,7 +482,25 @@ class CfgVehicles {
GVAR(canRepair) = 0;
};
- class Truck_03_base_F;
+ class Car_F: Car {
+ class HitPoints;
+ };
+ class Truck_F: Car_F {
+ class HitPoints: HitPoints {
+ class HitLBWheel;
+ class HitRBWheel;
+ };
+ };
+ class Truck_03_base_F: Truck_F {
+ class HitPoints: HitPoints {
+ class HitLBWheel: HitLBWheel {
+ name = "wheel_1_4_steering"; // return original values back to fix double wheel hitpoint
+ };
+ class HitRBWheel: HitRBWheel {
+ name = "wheel_2_4_steering";
+ };
+ };
+ };
class O_Truck_03_repair_F: Truck_03_base_F {
GVAR(canRepair) = 1;
transportRepair = 0;
diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf
index 5761206b3e..c409591911 100644
--- a/addons/repair/functions/fnc_addRepairActions.sqf
+++ b/addons/repair/functions/fnc_addRepairActions.sqf
@@ -34,7 +34,7 @@ if (_type in _initializedClasses) exitWith {};
private _hitPointsAddedNames = [];
private _hitPointsAddedStrings = [];
private _hitPointsAddedAmount = [];
-private _processedHitpoints = [];
+private _processedSelections = [];
private _icon = ["a3\ui_f\data\igui\cfg\actions\repair_ca.paa", "#FFFFFF"];
// Custom position can be defined via config for associated hitpoint
@@ -47,7 +47,7 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR
private _hitpoint = toLower (_hitPoints select _forEachIndex);
if (_selection in _wheelHitSelections) then {
// Wheels should always be unique
- if (_hitpoint in _processedHitpoints) exitWith {TRACE_3("Duplicate Wheel",_hitpoint,_forEachIndex,_selection);};
+ if (_selection in _processedSelections) exitWith {TRACE_3("Duplicate Wheel",_hitpoint,_forEachIndex,_selection);};
private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection];
@@ -68,13 +68,15 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR
_statement = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(repair)};
_action = [_name, _text, _icon, _statement, _condition, {}, [_hitpoint], _position, 2] call EFUNC(interact_menu,createAction);
[_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass);
+
+ _processedSelections pushBack _selection;
} else {
// Empty selections don't exist
if (_selection isEqualTo "") exitWith { TRACE_3("Skipping Empty Sel",_hitpoint,_forEachIndex,_selection); };
// Empty hitpoints don't contain enough information
if (_hitpoint isEqualTo "") exitWith { TRACE_3("Skipping Empty Hit",_hitpoint,_forEachIndex,_selection); };
// Ignore glass hitpoints
- if ((_hitPoint find "glass") != -1) exitWith { TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); };
+ if ((_hitpoint find "glass") != -1) exitWith { TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); };
// Ignore hitpoints starting with # (seems to be lights)
if ((_hitpoint select [0,1]) == "#") exitWith { TRACE_3("Skipping # hit",_hitpoint,_forEachIndex,_selection); };
// Ignore ERA/Slat armor (vanilla uses hitera_/hitslat_, pre-1.82 RHS uses era_)
@@ -125,7 +127,7 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR
if (_hitpoint in TRACK_HITPOINTS) then {
// Tracks should always be unique
- if (_hitpoint in _processedHitpoints) exitWith {TRACE_3("Duplicate Track",_hitpoint,_forEachIndex,_selection);};
+ if (_selection in _processedSelections) exitWith {TRACE_3("Duplicate Track",_hitpoint,_forEachIndex,_selection);};
_position = compile format ["private _return = _target selectionPosition ['%1', 'HitPoints']; _return set [1, 0]; _return", _selection];
TRACE_4("Adding RepairTrack",_hitpoint,_forEachIndex,_selection,_text);
private _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RepairTrack"] call DFUNC(canRepair)};
@@ -145,7 +147,7 @@ private _hitpointGroups = getArray(configFile >> "CfgVehicles" >> _type >> QGVAR
};
};
- _processedHitPoints pushBack _hitpoint;
+ _processedSelections pushBack _selection;
};
} forEach _hitSelections;
diff --git a/addons/safemode/functions/fnc_lockSafety.sqf b/addons/safemode/functions/fnc_lockSafety.sqf
index e3c1b71f30..c3ce5a8b86 100644
--- a/addons/safemode/functions/fnc_lockSafety.sqf
+++ b/addons/safemode/functions/fnc_lockSafety.sqf
@@ -60,7 +60,19 @@ if (_unit getVariable [QGVAR(actionID), -1] == -1) then {
};
if (_muzzle isEqualType "") then {
+ private _laserEnabled = _unit isIRLaserOn _weapon || {_unit isFlashlightOn _weapon};
+
_unit selectWeapon _muzzle;
+
+ if (
+ _laserEnabled
+ && {
+ _muzzle == primaryWeapon _unit // prevent UGL switch
+ || {"" == primaryWeapon _unit} // Arma switches to primary weapon if exists
+ }
+ ) then {
+ {_unit action [_x, _unit]} forEach ["GunLightOn", "IRLaserOn"];
+ };
};
// play fire mode selector sound
diff --git a/addons/safemode/functions/fnc_unlockSafety.sqf b/addons/safemode/functions/fnc_unlockSafety.sqf
index 5a787277e4..3194de6f14 100644
--- a/addons/safemode/functions/fnc_unlockSafety.sqf
+++ b/addons/safemode/functions/fnc_unlockSafety.sqf
@@ -30,8 +30,20 @@ if (_safedWeapons isEqualTo []) then {
_unit setVariable [QGVAR(actionID), -1];
};
+private _laserEnabled = _unit isIRLaserOn _weapon || {_unit isFlashlightOn _weapon};
+
_unit selectWeapon _muzzle;
+if (
+ _laserEnabled
+ && {
+ _muzzle == primaryWeapon _unit // prevent UGL switch
+ || {"" == primaryWeapon _unit} // Arma switches to primary weapon if exists
+ }
+) then {
+ {_unit action [_x, _unit]} forEach ["GunLightOn", "IRLaserOn"];
+};
+
if (inputAction "nextWeapon" > 0) then {
// switch to the last mode to roll over to first after the default nextWeapon action
// get weapon modes
diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf
index 0b5a174c5a..4e2ececf6c 100644
--- a/addons/ui/functions/fnc_setAdvancedElement.sqf
+++ b/addons/ui/functions/fnc_setAdvancedElement.sqf
@@ -6,7 +6,7 @@
* Arguments:
* 0: Element Name
* 1: Show/Hide Element
- * 2: Show Hint
+ * 2: Show Hint (default: false)
* 3: Force change even when disallowed (default: false)
*
* Return Value:
@@ -18,12 +18,13 @@
* Public: No
*/
-params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]] ];
+params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]]];
private _cachedElement = GVAR(configCache) getVariable _element;
-if (isNil "_cachedElement") exitWith {};
+if (isNil "_cachedElement") exitWith {TRACE_1("nil element",_this)};
if (!_force && {!GVAR(allowSelectiveUI)}) exitWith {
+ TRACE_1("not allowed",_this);
[LSTRING(Disallowed), 2] call EFUNC(common,displayTextStructured);
false
};
@@ -31,8 +32,14 @@ if (!_force && {!GVAR(allowSelectiveUI)}) exitWith {
_cachedElement params ["_idd", "_elements", "_location", "_conditions"];
// Exit if main vehicle type condition not fitting
-private _canUseWeapon = ACE_player call CBA_fnc_canUseWeapon;
-if ((_canUseWeapon && {_location == 2}) || {!_canUseWeapon && {_location == 1}}) exitWith {false};
+private _canUseWeaponOrInCargo = ACE_player call CBA_fnc_canUseWeapon || {-1 < vehicle ACE_player getCargoIndex ACE_player};
+if (
+ (_canUseWeaponOrInCargo && {_location == VEHICLE_ONLY})
+ || {!_canUseWeaponOrInCargo && {_location == GROUND_ONLY}}
+) exitWith {
+ TRACE_3("skip location",_this,_canUseWeaponOrInCargo,_location);
+ false
+};
// Get setting from config API
{
@@ -59,7 +66,7 @@ if (!_force) then {
};
};
-_show = [1, 0] select _show;
+private _fade = [1, 0] select _show;
// Disable/Enable elements
private _success = false;
@@ -69,9 +76,9 @@ private _success = false;
// Loop through IGUI displays as they can be present several times for some reason
{
if (_idd == ctrlIDD _x) then {
- //TRACE_3("Setting Element Visibility",_show,_idd,_idc);
+ TRACE_4("Setting Element Visibility",_element,_fade,_idd,_idc);
- (_x displayCtrl _idc) ctrlSetFade _show;
+ (_x displayCtrl _idc) ctrlSetFade _fade;
(_x displayCtrl _idc) ctrlCommit 0;
_success = true;
diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml
index 33b6dbb8c1..0df5016f7d 100644
--- a/addons/zeus/stringtable.xml
+++ b/addons/zeus/stringtable.xml
@@ -1522,10 +1522,12 @@
Paradrop Cargo
カーゴを空中投下
+ Zrzut ładunku (cargo)
No cargo loaded
カーゴは未積載
+ Niczego nie załadowano do cargo
diff --git a/docs/_config.yml b/docs/_config.yml
index 8db58136da..224559582d 100644
--- a/docs/_config.yml
+++ b/docs/_config.yml
@@ -9,16 +9,16 @@ ace:
version:
major: 3
minor: 12
- patch: 5
- build: 40
+ patch: 6
+ build: 43
acex:
githubUrl: https://github.com/acemod/ACEX
version:
major: 3
minor: 4
- patch: 1
- build: 11
+ patch: 2
+ build: 13
markdown: kramdown
diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml
index 28ce7d695a..a1d68d7786 100644
--- a/docs/_config_dev.yml
+++ b/docs/_config_dev.yml
@@ -9,16 +9,16 @@ ace:
version:
major: 3
minor: 12
- patch: 4
- build: 39
+ patch: 6
+ build: 43
acex:
githubUrl: https://github.com/acemod/ACEX
version:
major: 3
minor: 4
- patch: 0
- build: 10
+ patch: 2
+ build: 13
markdown: kramdown
diff --git a/docs/_includes/dependencies_list.md b/docs/_includes/dependencies_list.md
index 9509316a03..7e516cdb68 100644
--- a/docs/_includes/dependencies_list.md
+++ b/docs/_includes/dependencies_list.md
@@ -483,7 +483,7 @@
{% endif %}
{% if include.component == "compat_rksl_pm_ii" %}
-`RKSL_PMII`
+`RKSL_PMII`, `RKSL_PMII_525`
{% endif %}
{% if include.component == "compat_sma3_iansky" %}
diff --git a/docs/team.md b/docs/team.md
index 4998330e97..034fac4227 100644
--- a/docs/team.md
+++ b/docs/team.md
@@ -58,6 +58,7 @@ This lists all the maintainers responsible for project management and the overal
- [Kieran](https://github.com/kieran-s){:target="_blank"}
- [Giallustio](https://github.com/Giallustio){:target="_blank"}
- [654wak654](https://github.com/654wak654){:target="_blank"}
+- [mharis001](https://github.com/mharis001){:target="_blank"}
## Contributors
diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md
index 37214ba107..7a1481a299 100644
--- a/docs/wiki/framework/events-framework.md
+++ b/docs/wiki/framework/events-framework.md
@@ -46,6 +46,7 @@ MenuType: 0 = Interaction, 1 = Self Interaction
|----------|---------|---------|---------|---------|---------|
|`ace_interactMenuOpened` | [_menuType] | Local | Listen | Interaction Menu Opened
|`ace_interactMenuClosed` | [_menuType] | Local | Listen | Interaction Menu Closed
+|`ace_interact_menu_newControllableObject` | [_typeOf] | Local | Listen | New controlable object, only fires once per type (add self interactions)
### 2.4 Cargo (`ace_cargo`)
diff --git a/docs/wiki/framework/interactionMenu-framework.md b/docs/wiki/framework/interactionMenu-framework.md
index 44f4623ece..069baf351c 100644
--- a/docs/wiki/framework/interactionMenu-framework.md
+++ b/docs/wiki/framework/interactionMenu-framework.md
@@ -70,7 +70,7 @@ class CAManBase: Man {
Two steps, creating an action (array) and then adding it to either a class or object.
Important: `ace_common_fnc_canInteractWith` is not automatically checked and needs to be explicitly called.
-### 2.1 fnc_createAction
+### 3.1 fnc_createAction
`ace_interact_menu_fnc_createAction`
@@ -91,7 +91,7 @@ Important: `ace_common_fnc_canInteractWith` is not automatically checked and nee
*/
```
-### 2.2 fnc_addActionToClass
+### 3.2 fnc_addActionToClass
`ace_interact_menu_fnc_addActionToClass`
@@ -107,7 +107,7 @@ Important: `ace_common_fnc_canInteractWith` is not automatically checked and nee
```
By default this function will not use inheritance, so actions will only be added to the specific class.
-### 2.3 fnc_addActionToObject
+### 3.3 fnc_addActionToObject
`ace_interact_menu_fnc_addActionToObject`
@@ -121,7 +121,7 @@ By default this function will not use inheritance, so actions will only be added
*/
```
-### 2.4 fnc_addActionToZeus
+### 3.4 fnc_addActionToZeus
`ace_interact_menu_fnc_addActionToZeus`
@@ -133,7 +133,7 @@ By default this function will not use inheritance, so actions will only be added
*/
```
-### 2.5 Examples
+### 3.5 Examples
External:
@@ -177,7 +177,7 @@ _action = ["myMissionEvent1","Mission Event: Play Base Alarm","",_statement,{tru
[["ACE_ZeusActions"], _action] call ace_interact_menu_fnc_addActionToZeus;
```
-### 2.6 Advanced Example
+### 3.6 Advanced Example
This adds an interaction to a unit that allows passing items that the player is carrying.
@@ -221,3 +221,20 @@ _modifierFunc = {
_action = ["GiveItems", "?","",_statement,_condition,_insertChildren,[123],"",4,[false, false, false, true, false], _modifierFunc] call ace_interact_menu_fnc_createAction;
[q3, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_addActionToObject;
```
+
+### 3.7 Using `ace_interact_menu_newControllableObject` event
+
+CBA event `ace_interact_menu_newControllableObject` fires only once the first time the player controls a new object (new man, vehicle or controlled UAV)
+This is the ideal way to add self interaction actions, as adding them via `addActionToClass` will force self interaction actions to be compiled for classes that may never be used.
+
+```cpp
+// Example: Add radio self-action to all civilian cars
+["ace_interact_menu_newControllableObject", {
+ params ["_type"]; // string of the object's classname
+ if (!(_type isKindOf "Car")) exitWith {};
+ if ((getNumber (configFile >> "CfgVehicles" >> _type >> "side")) != 3) exitWith {};
+
+ private _action = ["playRadio","Play Radio","",{playMusic "NeverGonnaGiveYouUp"},{true}] call ace_interact_menu_fnc_createAction;
+ [_type, 1, ["ACE_SelfActions"], _action, true] call ace_interact_menu_fnc_addActionToClass;
+}] call CBA_fnc_addEventHandler;
+```
diff --git a/docs/wiki/frameworkx/field-rations-framework.md b/docs/wiki/frameworkx/field-rations-framework.md
new file mode 100644
index 0000000000..c5080e230d
--- /dev/null
+++ b/docs/wiki/frameworkx/field-rations-framework.md
@@ -0,0 +1,104 @@
+---
+layout: wiki
+title: Field Rations Framework
+description: Explains how to set-up ACEX Field Rations.
+group: framework
+parent: wiki
+mod: acex
+version:
+ major: 3
+ minor: 4
+ patch: 0
+---
+
+## 1. Config Values
+
+### 1.1 Consumable Items
+
+Config Name | Type | Description
+----------- | ---- | -----------
+`acex_field_rations_thirstQuenched` | Number | Amount of thirst quenched when item is consumed*
+`acex_field_rations_hungerSatiated` | Number | Amount of hunger satiated when item is consumed*
+`acex_field_rations_consumeTime` | Number | Time required to consume the item (in seconds)
+`acex_field_rations_consumeText` | String | Progress bar text (OPTIONAL)
+`acex_field_rations_consumeAnims` | Array | Animations to play when consuming item** (OPTIONAL)
+`acex_field_rations_consumeSounds` | Array | Sounds to play when consuming item** (OPTIONAL)
+`acex_field_rations_replacementItem` | String | Class name of replacement item to add on consumption (OPTIONAL)
+`acex_field_rations_refillItem` | String | Makes an item refillable, class name of item added when refilled (OPTIONAL)
+`acex_field_rations_refillAmount` | Number | Amount of water required to refill item (OPTIONAL)
+`acex_field_rations_refillTime` | Number | Time required to refill item (in seconds) (OPTIONAL)
+
+
+_* Value range is 0 to 100 and can be modified by the corresponding coefficient setting._
+
+_** Array is in format: STAND, CROUCH, PRONE. If player is in vehicle, the first element is used._
+
+### 1.2 Water Sources
+
+Config Name | Type | Description
+----------- | ---- | -----------
+`acex_field_rations_waterSupply` | Number | Amount of water inside the object (-1 - disabled, -10 - infinite) (OPTIONAL)
+`acex_field_rations_offset` | Array | Refill action offset relative to model (OPTIONAL)
+
+## 2. Events
+
+Event Name | Passed Parameter(s) | Locality | Description
+---------- | ------------------- | -------- | -----------
+`acex_rationConsumed` | [_player, _consumeItem, _replacementItem, _thirstQuenched, _hungerSatiated] | Local | Item consumed
+`acex_rationRefilled` | [_source, _player, _item, _refillItem, _refillAmount] | Local | Item refilled
+
+## 3. Scripting
+
+### 3.1 Getting water supply
+
+`acex_field_rations_fnc_getRemainingWater`
+
+```cpp
+* Returns the remaining water in a source.
+*
+* Arguments:
+* 0: Water source