diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf
index 8285a15519..6fdf99113c 100644
--- a/addons/common/XEH_preInit.sqf
+++ b/addons/common/XEH_preInit.sqf
@@ -11,6 +11,7 @@ PREP(addCanInteractWithCondition);
 PREP(addLineToDebugDraw);
 PREP(addSetting);
 PREP(addToInventory);
+PREP(assignObjectsInList);
 PREP(ambientBrightness);
 PREP(applyForceWalkStatus);
 PREP(ASLToPosition);
diff --git a/addons/common/functions/fnc_assignObjectsInList.sqf b/addons/common/functions/fnc_assignObjectsInList.sqf
new file mode 100644
index 0000000000..0d10066d01
--- /dev/null
+++ b/addons/common/functions/fnc_assignObjectsInList.sqf
@@ -0,0 +1,50 @@
+/*
+ * Author: Glowbal
+ * Loops through a string and filters out object names/variables to assign a value for given variable.
+ * Used by moduleAssign* within various parts of the ACE3 project.
+ *
+ * Arguments:
+ * 0: list <STRING>
+ * 1: variableName <STRING>
+ * 2: value <ANY>
+ * 3: Global <BOOL>
+ *
+ * Return Value:
+ * None <NIL>
+ *
+ * Public: No
+ */
+
+#include "script_component.hpp"
+
+private ["_splittedList", "_nilCheckPassedList"];
+params ["_list", "_variable", "_setting", "_global"];
+
+if (typeName _list == "STRING") then {
+    _splittedList = [_list, ","] call BIS_fnc_splitString;
+    _nilCheckPassedList = "";
+    {
+        _x = [_x] call FUNC(stringRemoveWhiteSpace);
+        if !(isnil _x) then {
+            if (_nilCheckPassedList == "") then {
+                _nilCheckPassedList = _x;
+            } else {
+                _nilCheckPassedList = _nilCheckPassedList + ","+ _x;
+            };
+        };
+    }foreach _splittedList;
+
+    _list = [] call compile format["[%1]",_nilCheckPassedList];
+};
+
+{
+    if (!isnil "_x") then {
+        if (typeName _x == typeName objNull) then {
+            if (local _x) then {
+                _x setvariable [_variable, _setting, _global];
+            };
+        };
+    };
+}foreach _list;
+
+true
diff --git a/addons/dragging/CfgEventHandlers.hpp b/addons/dragging/CfgEventHandlers.hpp
index e5c454e969..2ff7d07c0d 100644
--- a/addons/dragging/CfgEventHandlers.hpp
+++ b/addons/dragging/CfgEventHandlers.hpp
@@ -28,6 +28,11 @@ class Extended_Init_EventHandlers {
             init = QUOTE(_this call DFUNC(initObject));
         };
     };
+    class ACE_RepairItem_Base {
+        class ADDON {
+            init = QUOTE(_this call DFUNC(initObject));
+        };
+    };
 };
 
 class Extended_Killed_EventHandlers {
diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp
index 5ac84b7038..d4d791724b 100644
--- a/addons/dragging/CfgVehicles.hpp
+++ b/addons/dragging/CfgVehicles.hpp
@@ -83,4 +83,18 @@ class CfgVehicles {
         GVAR(canCarry) = 0;
         GVAR(canDrag) = 0;
     };
+
+    class ACE_RepairItem_Base: ThingX {};
+
+    class ACE_Track: ACE_RepairItem_Base {
+        GVAR(canCarry) = 1;
+        GVAR(carryPosition[]) = {0,1,1};
+        GVAR(carryDirection) = 0;
+    };
+
+    class ACE_Wheel: ACE_RepairItem_Base {
+        GVAR(canCarry) = 1;
+        GVAR(carryPosition[]) = {0,1,1};
+        GVAR(carryDirection) = 0;
+    };
 };
diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp
index 6a492b14ad..997974d2e3 100644
--- a/addons/interaction/CfgVehicles.hpp
+++ b/addons/interaction/CfgVehicles.hpp
@@ -548,7 +548,7 @@ class CfgVehicles {
             };
         };
     };
-    
+
     class StaticMGWeapon: StaticWeapon {};
     class HMG_01_base_F: StaticMGWeapon {};
     class HMG_01_high_base_F: HMG_01_base_F {
@@ -557,14 +557,14 @@ class CfgVehicles {
                   position = "[-0.172852,0.164063,-0.476091]";
               };
           };
-    };   
+    };
     class AA_01_base_F: StaticMGWeapon {
           class ACE_Actions: ACE_Actions {
               class ACE_MainActions: ACE_MainActions {
                   position = "[0,0.515869,-0.200671]";
               };
           };
-    };   
+    };
     class AT_01_base_F: StaticMGWeapon {
           class ACE_Actions: ACE_Actions {
               class ACE_MainActions: ACE_MainActions {
@@ -592,4 +592,16 @@ class CfgVehicles {
         };
         class ACE_SelfActions {};
     };
+
+    class ACE_RepairItem_Base: thingX {
+        class ACE_Actions {
+            class ACE_MainActions {
+                displayName = CSTRING(MainAction);
+                selection = "";
+                distance = 2;
+                condition = "true";
+            };
+        };
+        class ACE_SelfActions {};
+    };
 };
diff --git a/addons/repair/$PBOPREFIX$ b/addons/repair/$PBOPREFIX$
new file mode 100644
index 0000000000..d8fbd51195
--- /dev/null
+++ b/addons/repair/$PBOPREFIX$
@@ -0,0 +1 @@
+z\ace\addons\repair
\ No newline at end of file
diff --git a/addons/repair/ACE_Settings.hpp b/addons/repair/ACE_Settings.hpp
new file mode 100644
index 0000000000..0762b51ec9
--- /dev/null
+++ b/addons/repair/ACE_Settings.hpp
@@ -0,0 +1,65 @@
+class ACE_Settings {
+    class GVAR(DisplayTextOnRepair) {
+        displayName = CSTRING(SettingDisplayTextName);
+        description = CSTRING(SettingDisplayTextDesc);
+        typeName = "BOOL";
+        isClientSettable = 1;
+        value = 1;
+        category = CSTRING(categoryName);
+    };
+    class GVAR(engineerSetting_Repair) {
+        displayName = CSTRING(enginerSetting_Repair_name);
+        description = CSTRING(enginerSetting_Repair_description);
+        typeName = "SCALAR";
+        value = 1;
+        values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_RepairSpecialistOnly)};
+        category = CSTRING(categoryName);
+    };
+    class GVAR(engineerSetting_Wheel) {
+        displayName = CSTRING(enginerSetting_Wheel_name);
+        description = CSTRING(enginerSetting_Wheel_description);
+        typeName = "SCALAR";
+        value = 0;
+        values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_RepairSpecialistOnly)};
+        category = CSTRING(categoryName);
+    };
+    class GVAR(repairDamageThreshold) {
+        displayName = CSTRING(repairDamageThreshold_name);
+        description = CSTRING(repairDamageThreshold_description);
+        typeName = "SCALAR";
+        value = 0.6;
+        category = CSTRING(categoryName);
+    };
+    class GVAR(repairDamageThreshold_Engineer) {
+        displayName = CSTRING(repairDamageThreshold_Engineer_name);
+        description = CSTRING(repairDamageThreshold_Engineer_description);
+        typeName = "SCALAR";
+        value = 0.4;
+        category = CSTRING(categoryName);
+    };
+    class GVAR(consumeItem_ToolKit) {
+        displayName = CSTRING(consumeItem_ToolKit_name);
+        description = CSTRING(consumeItem_ToolKit_description);
+        typeName = "SCALAR";
+        value = 1;
+        values[] = {ECSTRING(common,No), ECSTRING(common,Yes)};
+        category = CSTRING(categoryName);
+    };
+
+    class GVAR(fullRepairLocation) {
+        displayName = CSTRING(fullRepairLocation);
+        description = CSTRING(fullRepairLocation_description);
+        typeName = "SCALAR";
+        value = 2;
+        values[] = {CSTRING(useAnywhere), CSTRING(repairVehicleOnly), CSTRING(repairFacilityOnly), CSTRING(vehicleAndFacility), ECSTRING(common,Disabled)};
+        category = CSTRING(categoryName);
+    };
+    class GVAR(engineerSetting_fullRepair) {
+        displayName = CSTRING(engineerSetting_fullRepair_name);
+        description = CSTRING(engineerSetting_fullRepair_description);
+        typeName = "SCALAR";
+        value = 3;
+        values[] = {CSTRING(engineerSetting_anyone), CSTRING(engineerSetting_EngineerOnly), CSTRING(engineerSetting_RepairSpecialistOnly)};
+        category = CSTRING(categoryName);
+    };
+};
diff --git a/addons/repair/ACE_repair.hpp b/addons/repair/ACE_repair.hpp
new file mode 100644
index 0000000000..01ad3aee23
--- /dev/null
+++ b/addons/repair/ACE_repair.hpp
@@ -0,0 +1,70 @@
+class ACE_Repair {
+    class Actions {
+        class ReplaceWheel {
+            displayName = CSTRING(ReplaceWheel);
+            displayNameProgress = CSTRING(ReplacingWheel);
+
+            locations[] = {"All"};
+            requiredEngineer = QGVAR(engineerSetting_Wheel);
+            repairingTime = 10;
+            repairingTimeSelfCoef = 1;
+            items[] = {"ToolKit"};
+            condition = QUOTE(call FUNC(canReplaceWheel));
+            itemConsumed = 0;
+
+            callbackSuccess = QUOTE(call FUNC(doReplaceWheel));
+            callbackFailure = "";
+            callbackProgress = "";
+
+            animationCaller = "Acts_carFixingWheel";
+            animationCallerProne = "Acts_carFixingWheel";
+            animationCallerSelf = "Acts_carFixingWheel";
+            animationCallerSelfProne = "Acts_carFixingWheel";
+            litter[] = {};
+        };
+        class RemoveWheel: ReplaceWheel {
+            displayName = CSTRING(RemoveWheel);
+            displayNameProgress = CSTRING(RemovingWheel);
+            condition = QUOTE(call FUNC(canRemoveWheel));
+            callbackSuccess = QUOTE(call FUNC(doRemoveWheel));
+        };
+        class MiscRepair: ReplaceWheel {
+            displayName = CSTRING(Repairing); // let's make empty string an auto generated string
+            displayNameProgress = CSTRING(RepairingHitPoint);
+            condition = QUOTE((_target getHitPointDamage _hitPoint) > ([_caller] call FUNC(getPostRepairDamage)));
+            requiredEngineer = 0;
+            repairingTime = 15;
+            callbackSuccess = QUOTE(call FUNC(doRepair));
+        };
+        class RepairTrack: MiscRepair {
+            displayName = CSTRING(Repairing);
+            displayNameProgress = CSTRING(RepairingHitPoint);
+            condition = QUOTE(call FUNC(canRepairTrack));
+            callbackSuccess = QUOTE(call FUNC(doRepairTrack));
+            requiredEngineer = QGVAR(engineerSetting_Wheel);
+        };
+        class RemoveTrack: MiscRepair {
+            displayName = CSTRING(RemoveTrack);
+            displayNameProgress = CSTRING(RemovingTrack);
+            condition = QUOTE(call FUNC(canRemoveTrack));
+            callbackSuccess = QUOTE(call FUNC(doRemoveTrack));
+            requiredEngineer = QGVAR(engineerSetting_Wheel);
+        };
+        class ReplaceTrack: RemoveTrack {
+            displayName = CSTRING(ReplaceTrack);
+            displayNameProgress = CSTRING(ReplacingTrack);
+            condition = QUOTE(call FUNC(canReplaceTrack));
+            callbackSuccess = QUOTE(call FUNC(doReplaceTrack));
+            requiredEngineer = QGVAR(engineerSetting_Wheel);
+        };
+        class FullRepair: MiscRepair {
+            displayName = CSTRING(fullRepair);
+            displayNameProgress = CSTRING(fullyRepairing);
+            requiredEngineer = QGVAR(engineerSetting_fullRepair);
+            repairLocations[] = {QGVAR(fullRepairLocation)};
+            repairingTime = 30;
+            condition = "damage (_this select 1) > 0";
+            callbackSuccess = QUOTE(call FUNC(doFullRepair));
+        };
+    };
+};
diff --git a/addons/repair/CfgEventHandlers.hpp b/addons/repair/CfgEventHandlers.hpp
new file mode 100644
index 0000000000..5113b9c8f4
--- /dev/null
+++ b/addons/repair/CfgEventHandlers.hpp
@@ -0,0 +1,44 @@
+
+class Extended_PreInit_EventHandlers {
+    class ADDON {
+        init = QUOTE(call COMPILE_FILE(XEH_preInit));
+    };
+};
+
+class Extended_PostInit_EventHandlers {
+    class ADDON {
+        init = QUOTE(call COMPILE_FILE(XEH_postInit));
+    };
+};
+
+class Extended_Init_EventHandlers {
+    class Car {
+        class ADDON {
+            init = QUOTE(_this call DFUNC(addRepairActions));
+        };
+    };
+
+    class Tank {
+        class ADDON {
+            init = QUOTE(_this call DFUNC(addRepairActions));
+        };
+    };
+
+    class Helicopter {
+        class ADDON {
+            init = QUOTE(_this call DFUNC(addRepairActions));
+        };
+    };
+
+    class Plane {
+        class ADDON {
+            init = QUOTE(_this call DFUNC(addRepairActions));
+        };
+    };
+
+    class Ship_F {
+        class ADDON {
+            init = QUOTE(_this call DFUNC(addRepairActions));
+        };
+    };
+};
diff --git a/addons/repair/CfgVehicleClasses.hpp b/addons/repair/CfgVehicleClasses.hpp
new file mode 100644
index 0000000000..0cd2e70942
--- /dev/null
+++ b/addons/repair/CfgVehicleClasses.hpp
@@ -0,0 +1,6 @@
+
+class CfgVehicleClasses {
+    class GVAR(items) {
+        displayName = "ACE";
+    };
+};
diff --git a/addons/repair/CfgVehicles.hpp b/addons/repair/CfgVehicles.hpp
new file mode 100644
index 0000000000..b70e415b53
--- /dev/null
+++ b/addons/repair/CfgVehicles.hpp
@@ -0,0 +1,340 @@
+
+#define MACRO_REPAIRVEHICLE \
+    class ACE_Actions { \
+        class ACE_MainActions { \
+            class GVAR(Repair) { \
+                displayName = CSTRING(Repair); \
+                condition = "true"; \
+                statement = ""; \
+                runOnHover = 1; \
+                showDisabled = 0; \
+                priority = 2; \
+                icon = "\A3\ui_f\data\igui\cfg\actions\repair_ca.paa"; \
+                distance = 4; \
+            }; \
+        }; \
+    };
+
+class CfgVehicles {
+    class ACE_Module;
+    // @todo localization for all the modules
+    class ACE_moduleRepairSettings: ACE_Module {
+        scope = 2;
+        displayName = CSTRING(moduleName);
+        icon = QUOTE(PATHTOF(ui\Icon_Module_Repair_ca.paa));   //@todo
+        category = "ACE";
+        function = QUOTE(DFUNC(moduleRepairSettings));
+        functionPriority = 1;
+        isGlobal = 1;
+        isTriggerActivated = 0;
+        author = ECSTRING(Common,ACETeam);
+        class Arguments {
+            class engineerSetting_Repair {
+                displayName = CSTRING(enginerSetting_Repair_name);
+                description = CSTRING(enginerSetting_Repair_description);
+                typeName = "NUMBER";
+                class values {
+                    class anyone { name = CSTRING(engineerSetting_anyone); value = 0; };
+                    class Engineer { name = CSTRING(engineerSetting_EngineerOnly); value = 1; default = 1; };
+                    class Special { name = CSTRING(engineerSetting_RepairSpecialistOnly); value = 2; };
+                };
+            };
+            class engineerSetting_Wheel {
+                displayName = CSTRING(enginerSetting_Wheel_name);
+                description = CSTRING(enginerSetting_Wheel_description);
+                typeName = "NUMBER";
+                class values {
+                    class anyone { name = CSTRING(engineerSetting_anyone); value = 0; default = 1; };
+                    class Engineer { name = CSTRING(engineerSetting_EngineerOnly); value = 1; };
+                    class Special { name = CSTRING(engineerSetting_RepairSpecialistOnly); value = 2; };
+                };
+            };
+            class repairDamageThreshold {
+                displayName = CSTRING(repairDamageThreshold_name);
+                description = CSTRING(repairDamageThreshold_description);
+                typeName = "NUMBER";
+                defaultValue = 0.6;
+            };
+            class repairDamageThreshold_Engineer {
+                displayName = CSTRING(repairDamageThreshold_Engineer_name);
+                description = CSTRING(repairDamageThreshold_Engineer_description);
+                typeName = "NUMBER";
+                defaultValue = 0.4;
+            };
+            class consumeItem_ToolKit {
+                displayName = CSTRING(consumeItem_ToolKit_name);
+                description = CSTRING(consumeItem_ToolKit_description);
+                typeName = "NUMBER";
+                class values {
+                    class keep { name = ECSTRING(common,No); value = 0; default = 1; };
+                    class remove { name = ECSTRING(common,Yes); value = 1; };
+                };
+            };
+            class fullRepairLocation {
+                displayName = CSTRING(fullRepairLocation);
+                description = CSTRING(fullRepairLocation_description);
+                typeName = "NUMBER";
+                class values {
+                    class anywhere { name = CSTRING(useAnywhere); value = 0; };
+                    class vehicle { name = CSTRING(repairVehicleOnly); value = 1; };
+                    class facility { name = CSTRING(repairFacilityOnly); value = 2; default = 1; };
+                    class vehicleAndFacility { name = CSTRING(vehicleAndFacility); value = 3; };
+                    class disabled { name = ECSTRING(common,Disabled); value = 4;};
+                };
+            };
+            class engineerSetting_fullRepair {
+                displayName = CSTRING(engineerSetting_fullRepair_name);
+                description = CSTRING(engineerSetting_fullRepair_description);
+                typeName = "NUMBER";
+                class values {
+                    class anyone { name = CSTRING(engineerSetting_anyone); value = 0; };
+                    class Engineer { name = CSTRING(engineerSetting_EngineerOnly); value = 1; };
+                    class Special { name = CSTRING(engineerSetting_RepairSpecialistOnly); value = 2; default = 1;};
+                };
+            };
+        };
+        class ModuleDescription {
+            description = CSTRING(moduleDescription);
+            sync[] = {};
+        };
+    };
+
+    class Module_F;
+    class ACE_moduleAssignEngineerRoles: Module_F {
+        scope = 2;
+        displayName = CSTRING(AssignEngineerRole_Module_DisplayName);
+        icon = QUOTE(PATHTOF(ui\Icon_Module_Repair_ca.paa));
+        category = "ACE";
+        function = QUOTE(DFUNC(moduleAssignEngineer));
+        functionPriority = 10;
+        isGlobal = 2;
+        isTriggerActivated = 0;
+        isDisposable = 0;
+        author = ECSTRING(common,ACETeam);
+        class Arguments {
+            class EnableList {
+                displayName = CSTRING(AssignEngineerRole_EnableList_DisplayName);
+                description = CSTRING(AssignEngineerRole_EnableList_Description);
+                defaultValue = "";
+                typeName = "STRING";
+            };
+            class role {
+                displayName = CSTRING(AssignEngineerRole_role_DisplayName);
+                description = CSTRING(AssignEngineerRole_role_Description);
+                typeName = "NUMBER";
+                class values {
+                    class none {
+                        name = CSTRING(AssignEngineerRole_role_none);
+                        value = 0;
+                    };
+                    class medic {
+                        name = CSTRING(AssignEngineerRole_role_engineer);
+                        value = 1;
+                        default = 1;
+                    };
+                    class doctor {
+                        name = CSTRING(AssignEngineerRole_role_specialist);
+                        value = 2;
+                    };
+                };
+            };
+        };
+        class ModuleDescription {
+            description = CSTRING(AssignEngineerRole_Module_Description);
+            sync[] = {};
+        };
+    };
+    class ACE_moduleAssignRepairVehicle: Module_F {
+        scope = 2;
+        displayName = CSTRING(AssignRepairVehicle_Module_DisplayName);
+        icon = QUOTE(PATHTOF(ui\Icon_Module_Repair_ca.paa));
+        category = "ACE";
+        function = QUOTE(DFUNC(moduleAssignRepairVehicle));
+        functionPriority = 10;
+        isGlobal = 2;
+        isTriggerActivated = 0;
+        isDisposable = 0;
+        author = ECSTRING(common,ACETeam);
+        class Arguments {
+            class EnableList {
+                displayName = CSTRING(AssignRepairVehicle_EnableList_DisplayName);
+                description = CSTRING(AssignRepairVehicle_EnableList_Description);
+                defaultValue = "";
+                typeName = "STRING";
+            };
+            class role {
+                displayName = CSTRING(AssignRepairVehicle_role_DisplayName);
+                description = CSTRING(AssignRepairVehicle_role_Description);
+                typeName = "NUMBER";
+                class values {
+                    class none {
+                        name = ECSTRING(common,No);
+                        value = 0;
+                    };
+                    class isVehicle {
+                        name = ECSTRING(common,Yes);
+                        value = 1;
+                        default = 1;
+                    };
+                };
+            };
+        };
+        class ModuleDescription {
+            description = CSTRING(AssignRepairVehicle_Module_Description);
+            sync[] = {};
+        };
+    };
+    class ACE_moduleAssignRepairFacility: ACE_moduleAssignRepairVehicle {
+        displayName = CSTRING(AssignRepairFacility_Module_DisplayName);
+        function = QUOTE(DFUNC(moduleAssignRepairFacility));
+        class Arguments {
+            class EnableList {
+                displayName = CSTRING(AssignRepairFacility_EnableList_DisplayName);
+                description = CSTRING(AssignRepairFacility_EnableList_Description);
+                defaultValue = "";
+                typeName = "STRING";
+            };
+            class role {
+                displayName = CSTRING(AssignRepairFacility_role_DisplayName);
+                description = CSTRING(AssignRepairFacility_role_Description);
+                typeName = "NUMBER";
+                class values {
+                    class none {
+                        name = ECSTRING(common,No);
+                        value = 0;
+                    };
+                    class isFacility {
+                        name = ECSTRING(common,Yes);
+                        value = 1;
+                        default = 1;
+                    };
+                };
+            };
+        };
+        class ModuleDescription {
+            description = CSTRING(AssignRepairFacility_Module_Description);
+            sync[] = {};
+        };
+    };
+
+
+    class LandVehicle;
+    class Car: LandVehicle {
+        MACRO_REPAIRVEHICLE
+
+        class ACE_Cargo {
+            class Cargo {
+                class ACE_Wheel {
+                    type = "ACE_Wheel";
+                    amount = 1;
+                };
+            };
+        };
+    };
+
+    class Tank: LandVehicle {
+        MACRO_REPAIRVEHICLE
+    };
+
+    class Air;
+    class Helicopter: Air {
+        MACRO_REPAIRVEHICLE
+    };
+
+    class Plane: Air {
+        MACRO_REPAIRVEHICLE
+    };
+
+    class Ship;
+    class Ship_F: Ship {
+        MACRO_REPAIRVEHICLE
+    };
+
+    class thingX;
+    class ACE_RepairItem_Base: thingX {
+        XEH_ENABLED;
+        icon = "iconObject_circle";
+        mapSize = 0.7;
+        accuracy = 0.2;
+        vehicleClass = QGVAR(items);
+        destrType = "DesturctNo";
+    };
+
+    class ACE_Track: ACE_RepairItem_Base {
+        ace_cargo_size = 2;
+        ace_cargo_canLoad = 1;
+        author = "Hawkins";
+        scope = 2;
+        model = QUOTE(PATHTOF(data\ace_track.p3d));
+        displayName = "$STR_ACE_Repair_SpareTrack";
+    };
+
+    class ACE_Wheel: ACE_RepairItem_Base {
+        ace_cargo_size = 1;
+        ace_cargo_canLoad = 1;
+        author = "Hawkins";
+        scope = 2;
+        model = QUOTE(PATHTOF(data\ace_wheel.p3d));
+        displayName = "$STR_ACE_Repair_SpareWheel";
+        picture = QUOTE(PATHTOF(ui\tire_ca.paa));
+    };
+
+    // disable vanilla repair
+    // "getNumber (_x >> ""transportRepair"") > 0" configClasses (configFile >> "CfgVehicles")
+
+    class Slingload_01_Base_F;
+    class B_Slingload_01_Repair_F: Slingload_01_Base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class Heli_Transport_04_base_F;
+    class O_Heli_Transport_04_repair_F: Heli_Transport_04_base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class Pod_Heli_Transport_04_base_F;
+    class Land_Pod_Heli_Transport_04_repair_F: Pod_Heli_Transport_04_base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class B_APC_Tracked_01_base_F;
+    class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class Offroad_01_base_F;
+    class Offroad_01_repair_base_F: Offroad_01_base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class B_Truck_01_mover_F;
+    class B_Truck_01_Repair_F: B_Truck_01_mover_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class B_Truck_01_fuel_F: B_Truck_01_mover_F {  // the fuel hemet apparently can repair. GJ BI
+        transportRepair = 0;
+    };
+
+    class Truck_02_base_F;
+    class Truck_02_box_base_F: Truck_02_base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+
+    class Truck_02_engineeral_base_F: Truck_02_box_base_F {
+        GVAR(canRepair) = 0;
+    };
+
+    class Truck_03_base_F;
+    class O_Truck_03_repair_F: Truck_03_base_F {
+        GVAR(canRepair) = 1;
+        transportRepair = 0;
+    };
+};
diff --git a/addons/repair/XEH_postInit.sqf b/addons/repair/XEH_postInit.sqf
new file mode 100644
index 0000000000..44ca157b0c
--- /dev/null
+++ b/addons/repair/XEH_postInit.sqf
@@ -0,0 +1,7 @@
+#include "script_component.hpp"
+
+["setVehicleDamage", {_this call FUNC(setDamage)}] call EFUNC(common,addEventHandler);
+["setVehicleHitPointDamage", {_this call FUNC(setHitPointDamage)}] call EFUNC(common,addEventHandler);
+
+// wheels
+["setWheelHitPointDamage", {(_this select 0) setHitPointDamage [_this select 1, _this select 2]}] call EFUNC(common,addEventHandler);
diff --git a/addons/repair/XEH_preInit.sqf b/addons/repair/XEH_preInit.sqf
new file mode 100644
index 0000000000..38de84a452
--- /dev/null
+++ b/addons/repair/XEH_preInit.sqf
@@ -0,0 +1,40 @@
+#include "script_component.hpp"
+
+ADDON = false;
+
+PREP(addRepairActions);
+PREP(canRemoveWheel);
+PREP(canRemoveTrack);
+PREP(canRepair);
+PREP(canRepairTrack);
+PREP(canReplaceWheel);
+PREP(canReplaceTrack);
+PREP(doRemoveWheel);
+PREP(doRemoveTrack);
+PREP(doRepair);
+PREP(doFullRepair);
+PREP(doRepairTrack);
+PREP(doReplaceWheel);
+PREP(doReplaceTrack);
+PREP(getPostRepairDamage);
+PREP(getWheelHitPointsWithSelections);
+PREP(hasItems);
+PREP(isEngineer);
+PREP(isInRepairFacility);
+PREP(isNearRepairVehicle);
+PREP(isRepairVehicle);
+PREP(moduleRepairSettings);
+PREP(moduleAssignEngineer);
+PREP(moduleAssignRepairVehicle);
+PREP(moduleAssignRepairFacility);
+PREP(normalizeHitPoints);
+PREP(repair);
+PREP(repair_failure);
+PREP(repair_success);
+PREP(setDamage);
+PREP(setHitPointDamage);
+PREP(spawnObject);
+PREP(useItem);
+PREP(useItems);
+
+ADDON = true;
diff --git a/addons/repair/config.cpp b/addons/repair/config.cpp
new file mode 100644
index 0000000000..9d447ffe5f
--- /dev/null
+++ b/addons/repair/config.cpp
@@ -0,0 +1,31 @@
+#include "script_component.hpp"
+
+class CfgPatches {
+    class ADDON {
+        units[] = {"ACE_Wheel", "ACE_Track"};
+        weapons[] = {};
+        requiredVersion = REQUIRED_VERSION;
+        requiredAddons[] = {"ace_common","ace_interact_menu"};
+        author[] = {"commy2", "Glowbal"};
+        authorUrl = "https://ace3mod.com";
+        VERSION_CONFIG;
+    };
+};
+
+#include "CfgEventHandlers.hpp"
+
+#include "CfgVehicleClasses.hpp"
+#include "CfgVehicles.hpp"
+
+#include "ACE_Settings.hpp"
+#include "ACE_repair.hpp"
+
+class CfgActions {
+    class None;
+    class Repair: None {
+        show = 0;
+    };
+    class RepairVehicle: None {
+        show = 0;
+    };
+};
\ No newline at end of file
diff --git a/addons/repair/data/ace_track.p3d b/addons/repair/data/ace_track.p3d
new file mode 100644
index 0000000000..904eebfc48
Binary files /dev/null and b/addons/repair/data/ace_track.p3d differ
diff --git a/addons/repair/data/ace_wheel.p3d b/addons/repair/data/ace_wheel.p3d
new file mode 100644
index 0000000000..f2b07b066f
Binary files /dev/null and b/addons/repair/data/ace_wheel.p3d differ
diff --git a/addons/repair/data/trailObjects.rvmat b/addons/repair/data/trailObjects.rvmat
new file mode 100644
index 0000000000..4fa521f376
--- /dev/null
+++ b/addons/repair/data/trailObjects.rvmat
@@ -0,0 +1,99 @@
+#define _ARMA_
+
+class StageTI
+{
+	texture = "a3\data_f\default_ti_ca.paa";
+};
+ambient[] = {1,1,1,1};
+diffuse[] = {1,1,1,1};
+forcedDiffuse[] = {0,0,0,0};
+emmisive[] = {0,0,0,0};
+specular[] = {0.0099999998,0.0099999998,0.0099999998,0.0099999998};
+specularPower = 500;
+PixelShaderID = "Super";
+VertexShaderID = "Super";
+class Stage1
+{
+	texture = "z\ace\addons\repair\data\trailObjects_nohq.paa";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
+class Stage2
+{
+	texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
+class Stage3
+{
+	texture = "#(argb,8,8,3)color(0,0,0,0,MC)";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
+class Stage4
+{
+	texture = "#(argb,8,8,3)color(1,1,1,1,AS)";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
+class Stage5
+{
+	texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
+class Stage6
+{
+	texture = "#(ai,64,64,1)fresnelGlass(2)";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
+class Stage7
+{
+	useWorldEnvMap = "true";
+	texture = "a3\data_f\env_land_ca.paa";
+	uvSource = "tex";
+	class uvTransform
+	{
+		aside[] = {1,0,0};
+		up[] = {0,1,0};
+		dir[] = {0,0,1};
+		pos[] = {0,0,0};
+	};
+};
diff --git a/addons/repair/data/trailObjects_co.paa b/addons/repair/data/trailObjects_co.paa
new file mode 100644
index 0000000000..25f2c4c1c0
Binary files /dev/null and b/addons/repair/data/trailObjects_co.paa differ
diff --git a/addons/repair/data/trailObjects_nohq.paa b/addons/repair/data/trailObjects_nohq.paa
new file mode 100644
index 0000000000..fc10e94aea
Binary files /dev/null and b/addons/repair/data/trailObjects_nohq.paa differ
diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf
new file mode 100644
index 0000000000..c267832298
--- /dev/null
+++ b/addons/repair/functions/fnc_addRepairActions.sqf
@@ -0,0 +1,124 @@
+/*
+ * Author: commy2
+ * Called from init eventhandler. Checks if the vehicles class already has the actions initialized. Otherwise add all available repair options.
+ *
+ * Arguments:
+ * 0: vehicle <OBJECT>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+#define TRACK_HITPOINTS ["HitLTrack", "HitRTrack"]
+
+params ["_vehicle"];
+TRACE_1("params", _vehicle);
+
+private ["_type", "_initializedClasses"];
+
+_type = typeOf _vehicle;
+
+_initializedClasses = GETMVAR(GVAR(initializedClasses),[]);
+
+// do nothing if the class is already initialized
+if (_type in _initializedClasses) exitWith {};
+// get all hitpoints
+private "_hitPoints";
+_hitPoints = [_vehicle] call EFUNC(common,getHitPointsWithSelections) select 0;
+
+// get hitpoints of wheels with their selections
+private ["_wheelHitPointsWithSelections", "_wheelHitPoints", "_wheelHitPointSelections"];
+
+_wheelHitPointsWithSelections = [_vehicle] call FUNC(getWheelHitPointsWithSelections);
+
+_wheelHitPoints = _wheelHitPointsWithSelections select 0;
+_wheelHitPointSelections = _wheelHitPointsWithSelections select 1;
+
+// add repair events to this vehicle class
+{
+    if (_x in _wheelHitPoints) then {
+        // add wheel repair action
+
+        private ["_icon", "_selection"];
+
+        _icon = QUOTE(PATHTOF(ui\tire_ca.paa));
+        _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa";
+        // textDefault = "<img image='\A3\ui_f\data\igui\cfg\actions\repair_ca.paa' size='1.8' shadow=2 />";
+        _selection = _wheelHitPointSelections select (_wheelHitPoints find _x);
+
+        private ["_name", "_text", "_condition", "_statement"];
+
+        // remove wheel action
+        _name = format  ["Remove_%1", _x];
+        _text = localize "STR_ACE_Repair_RemoveWheel";
+
+        _condition = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(canRepair)};
+        _statement = {[_this select 1, _this select 0, _this select 2 select 0, "RemoveWheel"] call DFUNC(repair)};
+
+        private "_action";
+        _action = [_name, _text, _icon, _statement, _condition, {}, [_x], _selection, 2] call EFUNC(interact_menu,createAction);
+        [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass);
+
+        // replace wheel action
+        _name = format  ["Replace_%1", _x];
+        _text = localize LSTRING(ReplaceWheel);
+
+        _condition = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(canRepair)};
+        _statement = {[_this select 1, _this select 0, _this select 2 select 0, "ReplaceWheel"] call DFUNC(repair)};
+
+        _action = [_name, _text, _icon, _statement, _condition, {}, [_x], _selection, 2] call EFUNC(interact_menu,createAction);
+        [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass);
+
+    } else {
+        // exit if the hitpoint is in the blacklist, e.g. glasses
+        if (_x in IGNORED_HITPOINTS) exitWith {};
+
+        // exit if the hitpoint is virtual
+        if (isText (configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _x >> "depends")) exitWith {};
+
+        // add misc repair action
+
+        private ["_name", "_text", "_icon", "_selection", "_condition", "_statement"];
+
+        _name = format ["Repair_%1", _x];
+
+        _text = format ["STR_ACE_Repair_%1", _x];
+
+        if (isLocalized _text) then {
+            _text = format [localize LSTRING(RepairHitpoint), localize _text];
+        } else {
+            _text = format [localize LSTRING(RepairHitpoint), _x];
+        };
+
+        _icon = "A3\ui_f\data\igui\cfg\actions\repair_ca.paa";
+        _selection = "";
+        _condition = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(canRepair)};
+        _statement = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(repair)};
+
+        if (_x in TRACK_HITPOINTS) then {
+            if (_x == "HitLTrack") then {
+                _selection = [-1.75, 0, -1.75];
+            } else {
+                _selection = [1.75, 0, -1.75];
+            };
+            private "_action";
+            _action = [_name, _text, _icon, _statement, _condition, {}, [_x, "RepairTrack"], _selection, 4] call EFUNC(interact_menu,createAction);
+            [_type, 0, [], _action] call EFUNC(interact_menu,addActionToClass);
+        } else {
+            private "_action";
+            _action = [_name, _text, _icon, _statement, _condition, {}, [_x, "MiscRepair"], _selection, 4] call EFUNC(interact_menu,createAction);
+            [_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass);
+        };
+    };
+} forEach _hitPoints;
+
+private ["_action", "_condition", "_statement"];
+
+_condition = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(canRepair)};
+_statement = {[_this select 1, _this select 0, _this select 2 select 0, _this select 2 select 1] call DFUNC(repair)};
+_action = [QGVAR(fullRepair), localize LSTRING(fullRepair), "A3\ui_f\data\igui\cfg\actions\repair_ca.paa", _statement, _condition, {}, ["", "fullRepair"], "", 4] call EFUNC(interact_menu,createAction);
+[_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass);
+// set class as initialized
+_initializedClasses pushBack _type;
+
+SETMVAR(GVAR(initializedClasses),_initializedClasses);
diff --git a/addons/repair/functions/fnc_canRemoveTrack.sqf b/addons/repair/functions/fnc_canRemoveTrack.sqf
new file mode 100644
index 0000000000..e428ac00a8
--- /dev/null
+++ b/addons/repair/functions/fnc_canRemoveTrack.sqf
@@ -0,0 +1,18 @@
+/*
+ * Author: commy2
+ * Check if the unit can remove given wheel of the vehicle.
+ *
+ * Arguments:
+ * 0: Unit that does the repairing <OBJECT>
+ * 1: vehicle to repair <OBJECT>
+ * 2: Selected hitpoint <STRING>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_target", "_hitPoint"];
+TRACE_3("params",_unit,_target,_hitPoint);
+
+alive _target && {_target getHitPointDamage _hitPoint < 1}
diff --git a/addons/repair/functions/fnc_canRemoveWheel.sqf b/addons/repair/functions/fnc_canRemoveWheel.sqf
new file mode 100644
index 0000000000..e428ac00a8
--- /dev/null
+++ b/addons/repair/functions/fnc_canRemoveWheel.sqf
@@ -0,0 +1,18 @@
+/*
+ * Author: commy2
+ * Check if the unit can remove given wheel of the vehicle.
+ *
+ * Arguments:
+ * 0: Unit that does the repairing <OBJECT>
+ * 1: vehicle to repair <OBJECT>
+ * 2: Selected hitpoint <STRING>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_target", "_hitPoint"];
+TRACE_3("params",_unit,_target,_hitPoint);
+
+alive _target && {_target getHitPointDamage _hitPoint < 1}
diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf
new file mode 100644
index 0000000000..0254dfbe14
--- /dev/null
+++ b/addons/repair/functions/fnc_canRepair.sqf
@@ -0,0 +1,92 @@
+/*
+ * Author: Glowbal
+ * Check if the repair action can be performed.
+ *
+ * Arguments:
+ * 0: The caller <OBJECT>
+ * 1: The target <OBJECT>
+ * 2: Selection name <STRING>
+ * 3: ACE_Engineeral_Treatments Classname <STRING>
+ *
+ * ReturnValue:
+ * Can Treat <BOOL>
+ *
+ * Public: Yes
+ */
+
+#include "script_component.hpp"
+
+params ["_caller", "_target", "_hitPoint", "_className"];
+TRACE_4("params",_caller,_target,_hitPoint,_className);
+
+private ["_config", "_engineerRequired", "_items", "_locations", "_return", "_condition", "_vehicleStateCondition"];
+
+_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className);
+if !(isClass _config) exitwith {false}; // or go for a default?
+if(isEngineOn _target) exitwith {false};
+
+_engineerRequired = if (isNumber (_config >> "requiredEngineer")) then {
+    getNumber (_config >> "requiredEngineer");
+} else {
+    // Check for required class
+    if (isText (_config >> "requiredEngineer")) exitwith {
+        missionNamespace getvariable [(getText (_config >> "requiredEngineer")), 0];
+    };
+    0;
+};
+if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitwith {false};
+
+_items = getArray (_config >> "items");
+if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitwith {false};
+
+_return = true;
+if (getText (_config >> "condition") != "") then {
+    _condition = getText (_config >> "condition");
+    if (isnil _condition) then {
+        _condition = compile _condition;
+    } else {
+        _condition = missionNamespace getvariable _condition;
+    };
+    if (typeName _condition == "BOOL") then {
+        _return = _condition;
+    } else {
+        _return = [_caller, _target, _hitPoint, _className] call _condition;
+    };
+};
+
+if (!_return) exitwith {false};
+
+_vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then {
+    missionNamespace getvariable [getText(_config >> "vehicleStateCondition"), 0]
+} else {
+    getNumber(_config >> "vehicleStateCondition")
+};
+// if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitwith {false};
+
+_locations = getArray (_config >> "repairLocations");
+if ("All" in _locations) exitwith {true};
+
+private ["_repairFacility", "_repairVeh"];
+_repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))};
+_repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))};
+
+{
+    if (_x == "field") exitwith {_return = true;};
+    if (_x == "RepairFacility" && _repairFacility) exitwith {_return = true;};
+    if (_x == "RepairVehicle" && _repairVeh) exitwith {_return = true;};
+    if !(isnil _x) exitwith {
+        private "_val";
+        _val = missionNamespace getvariable _x;
+        if (typeName _val == "SCALAR") then {
+            _return = switch (_val) do {
+                case 0: {true};
+                case 1: _repairVeh;
+                case 2: _repairFacility;
+                case 3: {{call _repairFacility || call _repairVeh}};
+            };
+            _return = call _return;
+        };
+    };
+} forEach _locations;
+
+_return && alive _target;
diff --git a/addons/repair/functions/fnc_canRepairTrack.sqf b/addons/repair/functions/fnc_canRepairTrack.sqf
new file mode 100644
index 0000000000..847715c5cb
--- /dev/null
+++ b/addons/repair/functions/fnc_canRepairTrack.sqf
@@ -0,0 +1,37 @@
+/*
+ * Author: commy2
+ * Check if the unit can replace given wheel of the vehicle.
+ *
+ * Arguments:
+ * 0: Unit that does the repairing (Object)
+ * 1: vehicle to repair (Object)
+ * 2: Selected hitpoint (String)
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_target", "_hitPoint", ["_wheel",false]];
+TRACE_4("params",_unit,_target,_hitPoint,_wheel);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+
+if (typeName _wheel == "OBJECT") then {
+    // not near interpret as objNull
+    if !(_wheel in nearestObjects [_unit, ["ACE_Track"], 5]) then {
+        _wheel = objNull;
+    };
+} else {
+    _wheel = objNull;
+
+    {
+        if ([_unit, _x, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {
+            _wheel = _x;
+        };
+    } forEach nearestObjects [_unit, ["ACE_Track"], 5];
+};
+
+if (isNull _wheel || damage _wheel >= 1) exitWith {false};
+
+alive _target && {_target getHitPointDamage _hitPoint > 0}
+
diff --git a/addons/repair/functions/fnc_canReplaceTrack.sqf b/addons/repair/functions/fnc_canReplaceTrack.sqf
new file mode 100644
index 0000000000..8ced60d63e
--- /dev/null
+++ b/addons/repair/functions/fnc_canReplaceTrack.sqf
@@ -0,0 +1,37 @@
+/*
+ * Author: commy2
+ * Check if the unit can replace given wheel of the vehicle.
+ *
+ * Arguments:
+ * 0: Unit that does the repairing (Object)
+ * 1: vehicle to repair (Object)
+ * 2: Selected hitpoint (String)
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_target", "_hitPoint", ["_wheel",false]];
+TRACE_4("params",_unit,_target,_hitPoint,_wheel);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+
+if (typeName _wheel == "OBJECT") then {
+    // not near interpret as objNull
+    if !(_wheel in nearestObjects [_unit, ["ACE_Track"], 5]) then {
+        _wheel = objNull;
+    };
+} else {
+    _wheel = objNull;
+
+    {
+        if ([_unit, _x, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {
+            _wheel = _x;
+        };
+    } forEach nearestObjects [_unit, ["ACE_Track"], 5];
+};
+
+if (isNull _wheel) exitWith {false};
+
+alive _target && {_target getHitPointDamage _hitPoint >= 1}
+
diff --git a/addons/repair/functions/fnc_canReplaceWheel.sqf b/addons/repair/functions/fnc_canReplaceWheel.sqf
new file mode 100644
index 0000000000..9251650e7f
--- /dev/null
+++ b/addons/repair/functions/fnc_canReplaceWheel.sqf
@@ -0,0 +1,43 @@
+/*
+ * Author: commy2
+ * Check if the unit can replace given wheel of the vehicle.
+ *
+ * Arguments:
+ * 0: Unit that does the repairing (Object)
+ * 1: vehicle to repair (Object)
+ * 2: Selected hitpoint (String)
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_target", "_hitPoint", ["_wheel",false]];
+TRACE_4("params",_unit,_target,_hitPoint,_wheel);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+//if !([_unit, _target, _hitpoint, "ReplaceWheel"] call FUNC(canRepair)) exitwith {false};
+
+//if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false};
+
+//if !([_unit, GVAR(engineerSetting_Wheel)] call FUNC(isEngineer)) exitWith {false};
+
+// check for a near wheel
+if (typeName _wheel == "OBJECT") then {
+    // not near interpret as objNull
+    if !(_wheel in nearestObjects [_unit, ["ACE_Wheel"], 5]) then {
+        _wheel = objNull;
+    };
+} else {
+    _wheel = objNull;
+
+    {
+        if ([_unit, _x, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {
+            _wheel = _x;
+        };
+    } forEach nearestObjects [_unit, ["ACE_Wheel"], 5];
+};
+
+if (isNull _wheel) exitWith {false};
+
+alive _target && {_target getHitPointDamage _hitPoint >= 1}
+
diff --git a/addons/repair/functions/fnc_doFullRepair.sqf b/addons/repair/functions/fnc_doFullRepair.sqf
new file mode 100644
index 0000000000..24454bbd62
--- /dev/null
+++ b/addons/repair/functions/fnc_doFullRepair.sqf
@@ -0,0 +1,17 @@
+/*
+ * Author: Glowbal
+ *
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * Stuff from progress bar.
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint"];
+TRACE_3("params",_unit,_vehicle,_hitPoint);
+
+_vehicle setDamage 0;
diff --git a/addons/repair/functions/fnc_doRemoveTrack.sqf b/addons/repair/functions/fnc_doRemoveTrack.sqf
new file mode 100644
index 0000000000..740edabf09
--- /dev/null
+++ b/addons/repair/functions/fnc_doRemoveTrack.sqf
@@ -0,0 +1,38 @@
+/*
+ * Author: commy2
+ *
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * Stuff from progress bar.
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint"];
+TRACE_3("params",_unit,_vehicle,_hitPoint);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+// get current hitpoint damage
+private "_hitPointDamage";
+_hitPointDamage = _vehicle getHitPointDamage _hitPoint;
+
+// can't remove destroyed or already removed wheel
+if (_hitPointDamage >= 1) exitWith {};
+
+// don't die by spawning / moving the wheel
+["fixCollision", _unit] call EFUNC(common,localEvent);
+
+// spawn wheel
+private "_wheel";
+_wheel = ["ACE_Track", getPosASL _unit] call FUNC(spawnObject);
+_wheel setdamage _hitPointDamage;
+
+// raise event to set the new hitpoint damage
+["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, 1]] call EFUNC(common,targetEvent);
+
+// display text message if enabled
+if (GVAR(DisplayTextOnRepair)) then {
+    [localize LSTRING(RemovedTrack)] call EFUNC(common,displayTextStructured);
+};
diff --git a/addons/repair/functions/fnc_doRemoveWheel.sqf b/addons/repair/functions/fnc_doRemoveWheel.sqf
new file mode 100644
index 0000000000..89fc76a341
--- /dev/null
+++ b/addons/repair/functions/fnc_doRemoveWheel.sqf
@@ -0,0 +1,38 @@
+/*
+ * Author: commy2
+ *
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * Stuff from progress bar.
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint"];
+TRACE_3("params",_unit,_vehicle,_hitPoint);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+// get current hitpoint damage
+private "_hitPointDamage";
+_hitPointDamage = _vehicle getHitPointDamage _hitPoint;
+
+// can't remove destroyed or already removed wheel
+if (_hitPointDamage >= 1) exitWith {};
+
+// don't die by spawning / moving the wheel
+["fixCollision", _unit] call EFUNC(common,localEvent);
+
+// spawn wheel
+private "_wheel";
+_wheel = ["ACE_Wheel", getPosASL _unit] call FUNC(spawnObject);
+_wheel setdamage _hitPointDamage;
+
+// raise event to set the new hitpoint damage
+["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, 1]] call EFUNC(common,targetEvent);
+
+// display text message if enabled
+if (GVAR(DisplayTextOnRepair)) then {
+    [localize LSTRING(RemovedWheel)] call EFUNC(common,displayTextStructured);
+};
diff --git a/addons/repair/functions/fnc_doRepair.sqf b/addons/repair/functions/fnc_doRepair.sqf
new file mode 100644
index 0000000000..8059003845
--- /dev/null
+++ b/addons/repair/functions/fnc_doRepair.sqf
@@ -0,0 +1,39 @@
+/*
+ * Author: commy2
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * 0: Stuff from progress bar. <ARRAY>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint"];
+TRACE_3("params",_unit,_vehicle,_hitPoint);
+
+// get current hitpoint damage
+private "_hitPointDamage";
+_hitPointDamage = _vehicle getHitPointDamage _hitPoint;
+
+_hitPointDamage = _hitPointDamage - 0.5;
+// don't use negative values for damage
+_hitPointDamage = _hitPointDamage max ([_unit] call FUNC(getPostRepairDamage));
+
+// raise event to set the new hitpoint damage
+["setVehicleHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent);
+
+// display text message if enabled
+if (GVAR(DisplayTextOnRepair)) then {
+    private "_text";
+    _text = format ["STR_ACE_Repair_%1", _hitPoint];
+
+    if (isLocalized _text) then {
+        _text = format [localize ([LSTRING(RepairedHitPointFully), LSTRING(RepairedHitPointPartially)] select (_hitPointDamage > 0)), localize _text];
+    } else {
+        _text = localize ([LSTRING(RepairedFully), LSTRING(RepairedPartially)] select (_hitPointDamage > 0));
+    };
+
+    [_text] call EFUNC(common,displayTextStructured);
+};
diff --git a/addons/repair/functions/fnc_doRepairTrack.sqf b/addons/repair/functions/fnc_doRepairTrack.sqf
new file mode 100644
index 0000000000..621d933d64
--- /dev/null
+++ b/addons/repair/functions/fnc_doRepairTrack.sqf
@@ -0,0 +1,45 @@
+/*
+ * Author: commy2
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * 0: Stuff from progress bar. <ARRAY>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint", "_classname"];
+TRACE_4("params",_unit,_vehicle,_hitPoint,_classname);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+
+private ["_hitPointDamage", "_newDamage", "_wheel"];
+
+_wheel = objNull;
+
+{
+    if ([_unit, _x, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {
+        _wheel = _x;
+    };
+} forEach nearestObjects [_unit, ["ACE_Track"], 5];
+if (isNull _wheel) exitwith {};
+
+// get current hitpoint damage
+
+_hitPointDamage = _vehicle getHitPointDamage _hitPoint;
+_newDamage = (1 - (damage _wheel)) / 4; // require 4 tracks to fully replace one side
+
+// can't replace a destroyed wheel
+if ((damage _wheel) >= 1) exitWith {};
+// don't die by spawning / moving the wheel
+_hitPointDamage = (_hitPointDamage - _newDamage) min 0;
+deleteVehicle _wheel;
+
+// raise event to set the new hitpoint damage
+["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent);
+
+// display text message if enabled
+if (GVAR(DisplayTextOnRepair)) then {
+    [LSTRING(ReplacedTrack)] call EFUNC(common,displayTextStructured);
+};
diff --git a/addons/repair/functions/fnc_doReplaceTrack.sqf b/addons/repair/functions/fnc_doReplaceTrack.sqf
new file mode 100644
index 0000000000..224508684b
--- /dev/null
+++ b/addons/repair/functions/fnc_doReplaceTrack.sqf
@@ -0,0 +1,48 @@
+/*
+ * Author: commy2
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * 0: Stuff from progress bar. <ARRAY>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint", "_classname"];
+TRACE_4("params",_unit,_vehicle,_hitPoint,_classname);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+
+private["_hitPointDamage", "_wheel"];
+
+_wheel = objNull;
+
+{
+    if ([_unit, _x, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {
+        _wheel = _x;
+    };
+} forEach nearestObjects [_unit, ["ACE_Track"], 5];
+if (isNull _wheel) exitwith {};
+
+// get current hitpoint damage
+_hitPointDamage = _vehicle getHitPointDamage _hitPoint;
+
+// can't replace not destroyed wheel
+if (_hitPointDamage < 1) exitWith {};
+
+// don't die by spawning / moving the wheel
+_hitPointDamage = damage _wheel;
+
+// can't replace a destroyed wheel
+if (_hitPointDamage >= 1) exitWith {};
+
+deleteVehicle _wheel;
+
+// raise event to set the new hitpoint damage
+["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent);
+
+// display text message if enabled
+if (GVAR(DisplayTextOnRepair)) then {
+    [LSTRING(ReplacedTrack)] call EFUNC(common,displayTextStructured);
+};
diff --git a/addons/repair/functions/fnc_doReplaceWheel.sqf b/addons/repair/functions/fnc_doReplaceWheel.sqf
new file mode 100644
index 0000000000..5051699497
--- /dev/null
+++ b/addons/repair/functions/fnc_doReplaceWheel.sqf
@@ -0,0 +1,48 @@
+/*
+ * Author: commy2
+ * Called by repair action / progress bar. Raise events to set the new hitpoint damage.
+ *
+ * Arguments:
+ * 0: Stuff from progress bar. <ARRAY>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint", "_classname"];
+TRACE_4("params",_unit,_vehicle,_hitPoint,_classname);
+// TODO [_unit, _wheel] call EFUNC(common,claim); on start of action
+
+private ["_hitPointDamage", "_wheel"];
+
+_wheel = objNull;
+
+{
+    if ([_unit, _x, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {
+        _wheel = _x;
+    };
+} forEach nearestObjects [_unit, ["ACE_Wheel"], 5];
+if (isNull _wheel) exitwith {};
+
+// get current hitpoint damage
+_hitPointDamage = _vehicle getHitPointDamage _hitPoint;
+
+// can't replace not destroyed wheel
+if (_hitPointDamage < 1) exitWith {};
+
+// don't die by spawning / moving the wheel
+_hitPointDamage = damage _wheel;
+
+// can't replace a destroyed wheel
+if (_hitPointDamage >= 1) exitWith {};
+
+deleteVehicle _wheel;
+
+// raise event to set the new hitpoint damage
+["setWheelHitPointDamage", _vehicle, [_vehicle, _hitPoint, _hitPointDamage]] call EFUNC(common,targetEvent);
+
+// display text message if enabled
+if (GVAR(DisplayTextOnRepair)) then {
+    [LSTRING(ReplacedWheel)] call EFUNC(common,displayTextStructured);
+};
diff --git a/addons/repair/functions/fnc_getPostRepairDamage.sqf b/addons/repair/functions/fnc_getPostRepairDamage.sqf
new file mode 100644
index 0000000000..c425f6569e
--- /dev/null
+++ b/addons/repair/functions/fnc_getPostRepairDamage.sqf
@@ -0,0 +1,12 @@
+// by comm2
+#include "script_component.hpp"
+
+params ["_unit"];
+TRACE_1("params",_unit);
+// TODO when near repair station, full repair?
+
+if (([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)})) exitwith {0};
+
+if ([_unit, GVAR(engineerSetting_Repair) + 1] call FUNC(isEngineer)) exitWith {GVAR(repairDamageThreshold_Engineer)};
+if ([_unit, GVAR(engineerSetting_Repair)] call FUNC(isEngineer)) exitWith {GVAR(repairDamageThreshold)};
+0.3;
diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf
new file mode 100644
index 0000000000..6719047737
--- /dev/null
+++ b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf
@@ -0,0 +1,76 @@
+/*
+ * Author: commy2
+ * Returns the wheel hitpoints and their selections.
+ *
+ * Arguments:
+ * 0: A vehicle <Object>
+ *
+ * Return Value:
+ * Wheel positions in model coordinates. <Array>
+ */
+#include "script_component.hpp"
+
+params ["_vehicle"];
+TRACE_1("params",_vehicle);
+
+// get the vehicles wheel config
+private "_wheels";
+_wheels = configfile >> "CfgVehicles" >> typeOf _vehicle >> "Wheels";
+
+// exit with nothing if the vehicle has no wheels class
+if !(isClass _wheels) exitWith {[[],[]]};
+
+// get all wheels and read selections from config
+private ["_selections", "_bones"];
+
+_wheels = "true" configClasses _wheels;
+
+_selections = [];
+_bones = [];
+{
+    _selections pushBack getText (_x >> "center");
+
+    private "_bone";
+    _bone = getText (_x >> "boneName");
+
+    _bone = toArray _bone;
+    _bone resize count "wheel_X_Y";  // this is a requirement for physx. Should work for all addon vehicles.
+    _bone = toString _bone;
+
+    _bones pushBack _bone;
+} forEach _wheels;
+
+// get hitpoints with their fire geometry selections
+private ["_hitPointsWithSelections", "_hitPoints", "_hitPointSelections"];
+
+_hitPointsWithSelections = [_vehicle] call EFUNC(common,getHitPointsWithSelections);
+
+_hitPoints = _hitPointsWithSelections select 0;
+_hitPointSelections = _hitPointsWithSelections select 1;
+
+// assign hitpoints to correct wheel selection by comparing bone name and fire geometry selection
+private ["_wheelHitPoints", "_wheelHitPointSelections"];
+
+_wheelHitPoints = [];
+_wheelHitPointSelections = [];
+{
+    private "_bone";
+    _bone = _x;
+
+    private "_index";
+
+    _index = -1;
+    {
+        if (_bone != "" && {_x find _bone == 0}) exitWith {  // same as above. Requirement for physx.
+            _index = _forEachIndex;
+        };
+    } forEach _hitPointSelections;
+
+    if (_index != -1) then {
+        _wheelHitPoints pushBack (_hitPoints select _index);
+        _wheelHitPointSelections pushBack (_selections select _forEachIndex);
+    };
+
+} forEach _bones;
+
+[_wheelHitPoints, _wheelHitPointSelections]
diff --git a/addons/repair/functions/fnc_hasItems.sqf b/addons/repair/functions/fnc_hasItems.sqf
new file mode 100644
index 0000000000..6167689faf
--- /dev/null
+++ b/addons/repair/functions/fnc_hasItems.sqf
@@ -0,0 +1,32 @@
+/*
+ * Author: Glowbal
+ * Check if the engineer has all items.
+ *
+ * Arguments:
+ * 0: Engineer <OBJECT>
+ * 1: Patient <OBJECT>
+ * 2: Items <ARRAY<STRING>>
+ *
+ * ReturnValue:
+ * Has the items <BOOL>
+ *
+ * Public: Yes
+ */
+#include "script_component.hpp"
+
+params ["_engineer", "_items"];
+TRACE_2("params",_engineer,_items);
+
+private ["_return"];
+
+_return = true;
+{
+    if (typeName _x == "ARRAY" && {({[_engineer, _x] call EFUNC(common,hasItem)} count _x == 0)}) exitwith {
+        _return = false;
+    };
+    if (typeName _x == "STRING" && {!([_engineer, _x] call EFUNC(common,hasItem))}) exitwith {
+        _return = false;
+    };
+} forEach _items;
+
+_return;
diff --git a/addons/repair/functions/fnc_isEngineer.sqf b/addons/repair/functions/fnc_isEngineer.sqf
new file mode 100644
index 0000000000..aa2368184a
--- /dev/null
+++ b/addons/repair/functions/fnc_isEngineer.sqf
@@ -0,0 +1,26 @@
+/*
+ * Author: Glowbal, KoffeinFlummi, commy2
+ * Check if a unit is any engineer class
+ *
+ * Arguments:
+ * 0: The Unit <OBJECT>
+ * 1: Class <NUMBER> <OPTIONAL>
+ *
+ * ReturnValue:
+ * Is in of engineer class <BOOL>
+ *
+ * Public: Yes
+ */
+#include "script_component.hpp"
+
+params ["_unit", ["_engineerN", 1]];
+TRACE_2("params",_unit,_engineerN);
+
+private ["_class"];
+_class = _unit getVariable ["ACE_IsEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer")];
+
+// This if statement is here for copmatability with the common variant of isEngineer, which requires a bool.
+// We cannot move this function to common because we require the GVAR(engineerSetting_Repair), which only makes sense to include in the repair module.
+if (typeName _class == "BOOL") then {_class = 1};
+
+_class >= (_engineerN min GVAR(engineerSetting_Repair));
\ No newline at end of file
diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf
new file mode 100644
index 0000000000..725cddd4c2
--- /dev/null
+++ b/addons/repair/functions/fnc_isInRepairFacility.sqf
@@ -0,0 +1,40 @@
+/*
+ * Author: Glowbal
+ * Checks if a unit is in a repair facility
+ *
+ * Arguments:
+ * 0: The Unit <OBJECT>
+ *
+ * ReturnValue:
+ * Is inside a repair facility <BOOL>
+ *
+ * Public: Yes
+ */
+
+#include "script_component.hpp"
+
+params ["_object"];
+TRACE_1("params",_object);
+
+private ["_position","_objects","_isInBuilding","_repairFacility"];
+
+_position = getPosASL _object;
+_isInBuilding = false;
+_repairFacility = [];
+
+_objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]);
+{
+    if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitwith {
+        _isInBuilding = true;
+    };
+} forEach _objects;
+
+if (!_isInBuilding) then {
+    _objects = position _object nearObjects 7.5;
+    {
+        if (((typeOf _x) in _repairFacility) || (_x getVariable ["ACE_isRepairFacility",0]) > 0) exitwith {
+            _isInBuilding = true;
+        };
+    } forEach _objects;
+};
+_isInBuilding;
diff --git a/addons/repair/functions/fnc_isNearRepairVehicle.sqf b/addons/repair/functions/fnc_isNearRepairVehicle.sqf
new file mode 100644
index 0000000000..126a0c40cb
--- /dev/null
+++ b/addons/repair/functions/fnc_isNearRepairVehicle.sqf
@@ -0,0 +1,28 @@
+/*
+ * Author: KoffeinFlummi
+ * Checks if a unit is in a engineeral vehicle.
+ *
+ * Arguments:
+ * 0: unit to be checked <OBJECT>
+ *
+ * Return Value:
+ * Is unit in engineeral vehicle? <BOOL>
+ *
+ * Public: Yes
+ */
+
+#include "script_component.hpp"
+
+params ["_unit"];
+TRACE_1("params",_unit);
+
+private ["_nearObjects", "_return"];
+
+_nearObjects = nearestObjects [_unit, ["Air","LandVehicle"], 20];
+
+_return = false;
+{
+    if ([_x] call FUNC(isRepairVehicle)) exitwith {_return = true;};
+} forEach _nearObjects;
+
+_return;
diff --git a/addons/repair/functions/fnc_isRepairVehicle.sqf b/addons/repair/functions/fnc_isRepairVehicle.sqf
new file mode 100644
index 0000000000..72da9783d1
--- /dev/null
+++ b/addons/repair/functions/fnc_isRepairVehicle.sqf
@@ -0,0 +1,20 @@
+/*
+ * Author: Glowbal
+ * Check if vehicle is a engineeral vehicle
+ *
+ * Arguments:
+ * 0: The Vehicle <OBJECT>
+ *
+ * ReturnValue:
+ * Is in of engineer class <BOOL>
+ *
+ * Public: Yes
+ */
+#include "script_component.hpp"
+
+params ["_vehicle"];
+TRACE_1("params",_vehicle);
+
+if (_vehicle isKindOf "CAManBase") exitwith {false};
+
+((_vehicle getVariable ["ACE_isRepairVehicle", getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(canRepair))]) > 0);
diff --git a/addons/repair/functions/fnc_moduleAssignEngineer.sqf b/addons/repair/functions/fnc_moduleAssignEngineer.sqf
new file mode 100644
index 0000000000..e5310bfa5a
--- /dev/null
+++ b/addons/repair/functions/fnc_moduleAssignEngineer.sqf
@@ -0,0 +1,29 @@
+/*
+ * Author: Glowbal
+ * Assign an engineer role to a unit
+ *
+ * Arguments:
+ * 0: The module logic <LOGIC>
+ * 1: units <ARRAY>
+ * 2: activated <BOOL>
+ *
+ * Return Value:
+ * None <NIL>
+ *
+ * Public: No
+ */
+
+#include "script_component.hpp"
+
+params ["_logic"];
+
+if (!isNull _logic) then {
+    private ["_list", "_setting"];
+    _list = _logic getvariable ["EnableList",""];
+    _setting = _logic getvariable ["role",0];
+
+    [_list, "ACE_IsEngineer", _setting, true] call EFUNC(common,assignObjectsInList);
+    [synchronizedObjects _logic, "ACE_IsEngineer", _setting, true] call EFUNC(common,assignObjectsInList);
+ };
+
+true
diff --git a/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf
new file mode 100644
index 0000000000..e9e60f4190
--- /dev/null
+++ b/addons/repair/functions/fnc_moduleAssignRepairFacility.sqf
@@ -0,0 +1,29 @@
+/*
+ * Author: Glowbal
+ * Assign an repair facility
+ *
+ * Arguments:
+ * 0: The module logic <LOGIC>
+ * 1: units <ARRAY>
+ * 2: activated <BOOL>
+ *
+ * Return Value:
+ * None <NIL>
+ *
+ * Public: No
+ */
+
+#include "script_component.hpp"
+
+params ["_logic"];
+
+if (!isNull _logic) then {
+    private ["_list", "_setting"];
+    _list = _logic getvariable ["EnableList",""];
+    _setting = _logic getvariable ["role",0];
+
+    [_list, "ACE_isRepairFacility", _setting, true] call EFUNC(common,assignObjectsInList);
+    [synchronizedObjects _logic, "ACE_isRepairFacility", _setting, true] call EFUNC(common,assignObjectsInList);
+ };
+
+true
diff --git a/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf
new file mode 100644
index 0000000000..991de2d8d6
--- /dev/null
+++ b/addons/repair/functions/fnc_moduleAssignRepairVehicle.sqf
@@ -0,0 +1,29 @@
+/*
+ * Author: Glowbal
+ * Assign an repair vehicle
+ *
+ * Arguments:
+ * 0: The module logic <LOGIC>
+ * 1: units <ARRAY>
+ * 2: activated <BOOL>
+ *
+ * Return Value:
+ * None <NIL>
+ *
+ * Public: No
+ */
+
+#include "script_component.hpp"
+
+params ["_logic"];
+
+if (!isNull _logic) then {
+    private ["_list", "_setting"];
+    _list = _logic getvariable ["EnableList",""];
+    _setting = _logic getvariable ["role",0];
+
+    [_list, "ACE_isRepairVehicle", _setting, true] call EFUNC(common,assignObjectsInList);
+    [synchronizedObjects _logic, "ACE_isRepairVehicle", _setting, true] call EFUNC(common,assignObjectsInList);
+ };
+
+true
diff --git a/addons/repair/functions/fnc_moduleRepairSettings.sqf b/addons/repair/functions/fnc_moduleRepairSettings.sqf
new file mode 100644
index 0000000000..7517d819c5
--- /dev/null
+++ b/addons/repair/functions/fnc_moduleRepairSettings.sqf
@@ -0,0 +1,29 @@
+/*
+ * Author: commy2
+ * Module for adjusting the repair damage settings
+ *
+ * Arguments:
+ * 0: The module logic <LOGIC>
+ *
+ * Return Value:
+ * None <NIL>
+ *
+ * Public: No
+ */
+#include "script_component.hpp"
+
+params ["_logic"];
+
+if (!isServer) exitWith {};
+
+[_logic, QGVAR(engineerSetting_Repair), "engineerSetting_Repair"] call EFUNC(common,readSettingFromModule);
+[_logic, QGVAR(engineerSetting_Wheel), "engineerSetting_Wheel"] call EFUNC(common,readSettingFromModule);
+[_logic, QGVAR(consumeItem_ToolKit), "consumeItem_ToolKit"] call EFUNC(common,readSettingFromModule);
+[_logic, QGVAR(repairDamageThreshold), "repairDamageThreshold"] call EFUNC(common,readSettingFromModule);
+[_logic, QGVAR(repairDamageThreshold_Engineer), "repairDamageThreshold_Engineer"] call EFUNC(common,readSettingFromModule);
+
+
+[_logic, QGVAR(fullRepairLocation), "fullRepairLocation"] call EFUNC(common,readSettingFromModule);
+[_logic, QGVAR(engineerSetting_fullRepair), "engineerSetting_fullRepair"] call EFUNC(common,readSettingFromModule);
+
+diag_log text "[ACE]: Repair Module Initialized.";
diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf
new file mode 100644
index 0000000000..7a39940794
--- /dev/null
+++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf
@@ -0,0 +1,53 @@
+/*
+ * Author: commy2
+ * Used to normalize dependant hitpoints. May overwrite some global variables that are named like hitpoints or "Total" though...
+ *
+ * Arguments:
+ * 0: A local vehicle with hitpoints. <OBJECT>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_vehicle"];
+TRACE_1("params",_vehicle);
+
+// can't execute all commands if the vehicle isn't local. exit here.
+if !(local _vehicle) exitWith {};
+
+private ["_hitPoints", "_config"];
+
+_hitPoints = [_vehicle] call EFUNC(common,getHitPoints);
+
+_config = configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints";
+
+// define global variables. Needed to parse the depends config entries. Also find dependent hitpoints.
+
+private ["_dependentHitPoints", "_dependentHitPointScripts"];
+
+_dependentHitPoints = [];
+_dependentHitPointScripts = [];
+
+Total = damage _vehicle;
+
+{
+    missionNamespace setVariable [_x, _vehicle getHitPointDamage _x];
+
+    if (isText (_config >> _x >> "depends")) then {
+        _dependentHitPoints pushBack _x;
+        _dependentHitPointScripts pushBack compile getText (_config >> _x >> "depends");
+    };
+
+} forEach _hitPoints;
+
+// apply normalized damage to all dependand hitpoints
+
+{
+    private "_damage";
+
+    _damage = call (_dependentHitPointScripts select _forEachIndex);
+
+    _vehicle setHitPointDamage [_x, _damage];
+
+} forEach _dependentHitPoints;
diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf
new file mode 100644
index 0000000000..263e0fec23
--- /dev/null
+++ b/addons/repair/functions/fnc_repair.sqf
@@ -0,0 +1,203 @@
+/*
+ * Author: Glowbal, KoffeinFlummi
+ * Starts the repair process
+ *
+ * Arguments:
+ * 0: The engineer <OBJECT>
+ * 1: The patient <OBJECT>
+ * 2: SelectionName <STRING>
+ * 3: repair classname <STRING>
+ *
+ * Return Value:
+ * Succesful repair started <BOOL>
+ *
+ * Public: Yes
+ */
+
+#include "script_component.hpp"
+
+params ["_caller", "_target", "_hitPoint", "_className"];
+TRACE_4("params",_calller,_target,_hitPoint,_className);
+
+private["_callbackProgress", "_callerAnim", "_calller", "_condition", "_config", "_consumeItems", "_displayText", "_engineerRequired", "_iconDisplayed", "_items", "_locations", "_repairTime", "_repairTimeConfig", "_return", "_usersOfItems", "_vehicleStateCondition", "_wpn"];
+
+_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className);
+if !(isClass _config) exitwith {false}; // or go for a default?
+
+_engineerRequired = if (isNumber (_config >> "requiredEngineer")) then {
+    getNumber (_config >> "requiredEngineer");
+} else {
+    // Check for required class
+    if (isText (_config >> "requiredEngineer")) exitwith {
+        missionNamespace getvariable [(getText (_config >> "requiredEngineer")), 0];
+    };
+    0;
+};
+if !([_caller, _engineerRequired] call FUNC(isEngineer)) exitwith {false};
+if (isEngineOn _target) exitwith {false};
+_items = getArray (_config >> "items");
+if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitwith {false};
+
+_return = true;
+if (getText (_config >> "condition") != "") then {
+    _condition = getText (_config >> "condition");
+    if (isnil _condition) then {
+        _condition = compile _condition;
+    } else {
+        _condition = missionNamespace getvariable _condition;
+    };
+    if (typeName _condition == "BOOL") then {
+        _return = _condition;
+    } else {
+        _return = [_caller, _target, _hitPoint, _className] call _condition;
+    };
+};
+if (!_return) exitwith {false};
+
+_vehicleStateCondition = if (isText(_config >> "vehicleStateCondition")) then {
+    missionNamespace getvariable [getText(_config >> "vehicleStateCondition"), 0]
+} else {
+    getNumber(_config >> "vehicleStateCondition")
+};
+// if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitwith {false};
+
+_locations = getArray (_config >> "repairLocations");
+if ("All" in _locations) exitwith {true};
+
+private ["_repairFacility", "_repairVeh"];
+_repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))};
+_repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))};
+
+{
+    if (_x == "field") exitwith {_return = true;};
+    if (_x == "RepairFacility" && _repairFacility) exitwith {_return = true;};
+    if (_x == "RepairVehicle" && _repairVeh) exitwith {_return = true;};
+    if !(isnil _x) exitwith {
+        private "_val";
+        _val = missionNamespace getvariable _x;
+        if (typeName _val == "SCALAR") then {
+            _return = switch (_val) do {
+                case 0: {true};
+                case 1: _repairVeh;
+                case 2: _repairFacility;
+                case 3: {{call _repairFacility || call _repairVeh}};
+            };
+            _return = call _return;
+        };
+    };
+} forEach _locations;
+
+if !(_return && alive _target) exitwith {false};
+
+_consumeItems = if (isNumber (_config >> "itemConsumed")) then {
+    getNumber (_config >> "itemConsumed");
+} else {
+    // Check for required class
+    if (isText (_config >> "itemConsumed")) exitwith {
+        missionNamespace getvariable [(getText (_config >> "itemConsumed")), 0];
+    };
+    0;
+};
+
+_usersOfItems = [];
+if (_consumeItems > 0) then {
+    _usersOfItems = ([_caller, _target, _items] call FUNC(useItems)) select 1;
+};
+
+// Parse the config for the progress callback
+_callbackProgress = getText (_config >> "callbackProgress");
+if (_callbackProgress == "") then {
+    _callbackProgress = "true";
+};
+if (isNil _callbackProgress) then {
+    _callbackProgress = compile _callbackProgress;
+} else {
+    _callbackProgress = missionNamespace getvariable _callbackProgress;
+};
+
+
+// Player Animation
+_callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE");
+_caller setvariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller];
+
+// Cannot use secondairy weapon for animation
+if (currentWeapon _caller == secondaryWeapon _caller) then {
+    _caller selectWeapon (primaryWeapon _caller);
+};
+
+_wpn = ["non", "rfl", "pst"] select (1 + ([primaryWeapon _caller, handgunWeapon _caller] find (currentWeapon _caller)));
+_callerAnim = [_callerAnim, "[wpn]", _wpn] call CBA_fnc_replace;
+if (vehicle _caller == _caller && {_callerAnim != ""}) then {
+    if (primaryWeapon _caller == "") then {
+        _caller addWeapon "ACE_FakePrimaryWeapon";
+    };
+    if (currentWeapon _caller == "") then {
+        _caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here
+    };
+
+    if (stance _caller == "STAND") then {
+        _caller setvariable [QGVAR(repairPrevAnimCaller), "amovpknlmstpsraswrfldnon"];
+    } else {
+        _caller setvariable [QGVAR(repairPrevAnimCaller), animationState _caller];
+    };
+    [_caller, _callerAnim] call EFUNC(common,doAnimation);
+};
+
+//Get repair time
+_repairTime = if (isNumber (_config >> "repairingTime")) then {
+    getNumber (_config >> "repairingTime");
+} else {
+    if (isText (_config >> "repairingTime")) exitwith {
+        _repairTimeConfig = getText(_config >> "repairingTime");
+        if (isnil _repairTimeConfig) then {
+            _repairTimeConfig = compile _repairTimeConfig;
+        } else {
+            _repairTimeConfig = missionNamespace getvariable _repairTimeConfig;
+        };
+        if (typeName _repairTimeConfig == "SCALAR") exitwith {
+            _repairTimeConfig;
+        };
+        [_caller, _target, _hitPoint, _className] call _repairTimeConfig;
+    };
+    0;
+};
+
+private ["_text", "_processText"];
+_processText = getText (_config >> "displayNameProgress");
+_text = format ["STR_ACE_Repair_%1", _hitPoint];
+if (isLocalized _text) then {
+    _text = format [_processText, localize _text];
+} else {
+    _text = _processText;
+};
+
+// Start repair
+[
+    _repairTime,
+    [_caller, _target, _hitPoint, _className, _items, _usersOfItems],
+    DFUNC(repair_success),
+    DFUNC(repair_failure),
+    _text,
+    _callbackProgress,
+    []
+] call EFUNC(common,progressBar);
+
+// Display Icon
+_iconDisplayed = getText (_config >> "actionIconPath");
+if (_iconDisplayed != "") then {
+    [QGVAR(repairActionIcon), true, _iconDisplayed, [1,1,1,1], getNumber(_config >> "actionIconDisplayTime")] call EFUNC(common,displayIcon);
+};
+
+// handle display of text/hints
+_displayText = "";
+if (_target != _caller) then {
+    _displayText = getText(_config >> "displayTextOther");
+} else {
+    _displayText = getText(_config >> "displayTextSelf");
+};
+
+if (_displayText != "") then {
+    ["displayTextStructured", [_caller], [[_displayText, [_caller] call EFUNC(common,getName), [_target] call EFUNC(common,getName)], 1.5, _caller]] call EFUNC(common,targetEvent);
+};
+
+true;
diff --git a/addons/repair/functions/fnc_repairVehicle.sqf b/addons/repair/functions/fnc_repairVehicle.sqf
new file mode 100644
index 0000000000..becdcb366d
--- /dev/null
+++ b/addons/repair/functions/fnc_repairVehicle.sqf
@@ -0,0 +1,45 @@
+/*
+ * Author: commy2
+ *
+ * Start a repair action and open progress bar.
+ *
+ * Arguments:
+ * 0: Unit that does the repairing (Object)
+ * 1: vehicle to repair (Object)
+ * 2: Selected hitpoint (String)
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_unit", "_vehicle", "_hitPoint"];
+TRACE_3("params",_unit,_vehicle,_hitPoint);
+
+// exit if not a valid hitpoint
+if !(_hitPoint in ([_vehicle] call EFUNC(common,getHitPoints))) exitWith {};
+
+// calculate time to fully repair the hitpoint
+private ["_damage", "_time"];
+
+_damage = _vehicle getHitPointDamage _hitPoint;
+
+_time = (5 + 10 * _damage) * ([1.5, 1] select ([_unit, GVAR(engineerSetting_Repair) + 1] call FUNC(isEngineer)));
+
+// get string of the hitpoint
+private "_text";
+_text = format ["STR_ACE_Repair_%1", _hitPoint];
+
+if (isLocalized _text) then {
+    _text = format [localize LSTRING(RepairingHitPoint), localize _text];
+} else {
+    _text = localize LSTRING(Repairing);
+};
+
+// open the loading bar
+[_time, [_unit, _vehicle, _hitPoint], {_this call DFUNC(doRepair)}, {_this call DFUNC(doRepair)}, _text, {(_this select 0) call DFUNC(canRepair)}, []] call EFUNC(common,progressBar);
+
+// do animation
+[_unit] call EFUNC(common,goKneeling);
+
+// @todo play sound
diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf
new file mode 100644
index 0000000000..b1f62cecb9
--- /dev/null
+++ b/addons/repair/functions/fnc_repair_failure.sqf
@@ -0,0 +1,56 @@
+/*
+ * Author: KoffeinFlummi, Glowbal
+ * Callback when the repair fails
+ *
+ * Arguments:
+ * 0: The engineer <OBJECT>
+ * 1: The patient <OBJECT>
+ * 2: SelectionName <STRING>
+ * 3: Treatment classname <STRING>
+ * 4: Items available <ARRAY<STRING>>
+ *
+ * Return Value:
+ * nil
+ *
+ * Public: No
+ */
+#include "script_component.hpp"
+
+params ["_args"];
+_args params ["_caller", "_target","_selectionName","_className","","_usersOfItems"];
+TRACE_5("params",_caller,_target,_selectionName,_className,_usersOfItems);
+
+private ["_config","_callback", "_usersOfItems", "_weaponSelect"];
+
+if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
+    _caller removeWeapon "ACE_FakePrimaryWeapon";
+};
+if (vehicle _caller == _caller) then {
+    [_caller, _caller getvariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation);
+};
+_caller setvariable [QGVAR(repairPrevAnimCaller), nil];
+
+_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnrepair), ""]);
+if (_weaponSelect != "") then {
+    _caller selectWeapon _weaponSelect;
+} else {
+    _caller action ["SwitchWeapon", _caller, _caller, 99];
+};
+
+{
+    (_x select 0) addItem (_x select 1);
+} forEach _usersOfItems;
+
+// Record specific callback
+_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className);
+
+_callback = getText (_config >> "callbackFailure");
+if (isNil _callback) then {
+    _callback = compile _callback;
+} else {
+    _callback = missionNamespace getvariable _callback;
+};
+
+_args call _callback;
+
+// _args call FUNC(createLitter);
diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf
new file mode 100644
index 0000000000..7b19ef64de
--- /dev/null
+++ b/addons/repair/functions/fnc_repair_success.sqf
@@ -0,0 +1,52 @@
+/*
+ * Author: KoffeinFlummi, Glowbal
+ * Callback when the repair is completed
+ *
+ * Arguments:
+ * 0: The engineer <OBJECT>
+ * 1: The patient <OBJECT>
+ * 2: SelectionName <STRING>
+ * 3: Treatment classname <STRING>
+ * 4: Items available <ARRAY<STRING>>
+ *
+ * Return Value:
+ * nil
+ *
+ * Public: No
+ */
+
+#include "script_component.hpp"
+
+params ["_args"];
+_args params ["_caller", "_target","_selectionName","_className"];
+TRACE_4("params",_caller,_target,_selectionName,_className);
+
+private ["_config","_callback", "_weaponSelect"];
+
+if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
+    _caller removeWeapon "ACE_FakePrimaryWeapon";
+};
+if (vehicle _caller == _caller) then {
+    [_caller, _caller getvariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation);
+};
+_caller setvariable [QGVAR(repairPrevAnimCaller), nil];
+
+_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnrepair), ""]);
+if (_weaponSelect != "") then {
+    _caller selectWeapon _weaponSelect;
+} else {
+    _caller action ["SwitchWeapon", _caller, _caller, 99];
+};
+
+// Record specific callback
+_config = (ConfigFile >> "ACE_Repair" >> "Actions" >> _className);
+
+_callback = getText (_config >> "callbackSuccess");
+if (isNil _callback) then {
+    _callback = compile _callback;
+} else {
+    _callback = missionNamespace getvariable _callback;
+};
+_args call _callback;
+
+// _args call FUNC(createLitter);
diff --git a/addons/repair/functions/fnc_setDamage.sqf b/addons/repair/functions/fnc_setDamage.sqf
new file mode 100644
index 0000000000..c739a2c9fc
--- /dev/null
+++ b/addons/repair/functions/fnc_setDamage.sqf
@@ -0,0 +1,40 @@
+/*
+ * Author: commy2
+ * Sets the structural damage of a vehicle without altering the hitPoints. Requires local vehicle.
+ *
+ * Arguments:
+ * 0: vehicle to damage <OBJECT>
+ * 1: Total damage <NUMBER>
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_vehicle", "_damage"];
+TRACE_2("params",_vehicle,_damage);
+
+// can't execute all commands if the vehicle isn't local. exit here.
+if !(local _vehicle) exitWith {};
+
+// save array with damage values of all hitpoints
+private ["_hitPoints", "_hitPointDamages"];
+
+_hitPoints = [_vehicle] call EFUNC(common,getHitpoints);
+
+_hitPointDamages = [];
+
+{
+    _hitPointDamages set [_forEachIndex, _vehicle getHitPointDamage _x];
+} forEach _hitPoints;
+
+// set damage of the vehicle
+_vehicle setDamage _damage;
+
+// restore original hitpoint damage values
+{
+    _vehicle setHitPointDamage [_x, _hitPointDamages select _forEachIndex];
+} forEach _hitPoints;
+
+// normalize hitpoints
+[_vehicle] call FUNC(normalizeHitPoints);
diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf
new file mode 100644
index 0000000000..d4595960e4
--- /dev/null
+++ b/addons/repair/functions/fnc_setHitPointDamage.sqf
@@ -0,0 +1,81 @@
+/*
+ * Author: commy2
+ * Set the hitpoint damage and change the structural damage acordingly. Requires local vehicle.
+ *
+ * Arguments:
+ * 0: vehicle
+ * 1: hitpoint
+ * 2: damage
+ *
+ * Return Value:
+ * NONE
+ */
+#include "script_component.hpp"
+
+params ["_vehicle", "_hitPoint", "_hitPointDamage"];
+TRACE_3("params",_vehicle,_hitPoint,_hitPointDamage);
+
+// can't execute all commands if the vehicle isn't local. exit here.
+if !(local _vehicle) exitWith {};
+
+// get all valid hitpoints
+private ["_hitPoints", "_hitPointsWithSelections"];
+
+_hitPoints = [_vehicle] call EFUNC(common,getHitpoints);
+_hitPointsWithSelections = [_vehicle] call EFUNC(common,getHitpointsWithSelections) select 0;
+
+// exit if the hitpoint is not valid
+if !(_hitPoint in _hitPoints) exitWith {systemChat format["NOT A VALID HITPOINT: %1",_hitpoint]};
+
+// save array with damage values of all hitpoints
+private "_hitPointDamages";
+_hitPointDamages = [];
+
+{
+    _hitPointDamages set [_forEachIndex, (_vehicle getHitPointDamage _x)];
+} forEach _hitPoints;
+
+// save structural damage and sum of hitpoint damages
+private ["_damageOld", "_hitPointDamageSumOld"];
+
+_damageOld = damage _vehicle;
+
+_hitPointDamageSumOld = 0;
+{
+    if (!(_x in IGNORED_HITPOINTS) && {!isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")}) then {
+        _hitPointDamageSumOld = _hitPointDamageSumOld + (_hitPointDamages select (_hitPoints find _x));
+    };
+} forEach _hitPointsWithSelections;
+
+// set new damage in array
+_hitPointDamages set [_hitPoints find _hitPoint, _hitPointDamage];
+
+// save sum of new hitpoint damages
+private "_hitPointDamageSumNew";
+
+_hitPointDamageSumNew = 0;
+{
+    if (!(_x in IGNORED_HITPOINTS) && {!isText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "HitPoints" >> _x >> "depends")}) then {
+        _hitPointDamageSumNew = _hitPointDamageSumNew + (_hitPointDamages select (_hitPoints find _x));
+    };
+} forEach _hitPointsWithSelections;
+
+// calculate new strctural damage
+private "_damageNew";
+_damageNew = _hitPointDamageSumNew / count _hitPoints;
+
+if (_hitPointDamageSumOld > 0) then {
+    _damageNew = _damageOld * (_hitPointDamageSumNew / _hitPointDamageSumOld);
+};
+
+// set new structural damage value
+_vehicle setDamage _damageNew;
+
+// set the new damage for that hit point
+
+{
+    _vehicle setHitPointDamage [_x, _hitPointDamages select _forEachIndex];
+} forEach _hitPoints;
+
+// normalize hitpoints
+// [_vehicle] call FUNC(normalizeHitPoints);
diff --git a/addons/repair/functions/fnc_spawnObject.sqf b/addons/repair/functions/fnc_spawnObject.sqf
new file mode 100644
index 0000000000..efe64ec9d5
--- /dev/null
+++ b/addons/repair/functions/fnc_spawnObject.sqf
@@ -0,0 +1,16 @@
+// by commy2
+#include "script_component.hpp"
+
+params ["_item", "_position", ["_damage", 0]];
+TRACE_3("params",_item,_position,_damage);
+
+// randomized end position
+_position = _position vectorAdd [1 - random 2, 1 - random 2, 0];
+
+_item = createVehicle [_item, _position, [], 0, "NONE"];
+_item setPosASL _position;
+
+["fixCollision", _item] call EFUNC(common,localEvent);
+["fixPosition", _item] call EFUNC(common,localEvent);
+
+_item setDamage _damage;
diff --git a/addons/repair/functions/fnc_useItem.sqf b/addons/repair/functions/fnc_useItem.sqf
new file mode 100644
index 0000000000..2309c25bd8
--- /dev/null
+++ b/addons/repair/functions/fnc_useItem.sqf
@@ -0,0 +1,24 @@
+/*
+ * Author: Glowbal
+ * Use Equipment if any is available.
+ *
+ * Arguments:
+ * 0: Engineer <OBJECT>
+ * 2: Item <STRING>
+ *
+ * ReturnValue:
+ * <NIL>
+ *
+ * Public: Yes
+ */
+
+#include "script_component.hpp"
+
+params ["_engineer", "_item"];
+TRACE_2("params",_engineer,_item);
+
+if ([_engineer, _item] call EFUNC(common,hasItem)) exitwith {
+    [[_engineer, _item], QUOTE(EFUNC(common,useItem)), _engineer] call EFUNC(common,execRemoteFnc); /* TODO Replace by event system */
+    [true, _engineer];
+};
+[false, objNull];
diff --git a/addons/repair/functions/fnc_useItems.sqf b/addons/repair/functions/fnc_useItems.sqf
new file mode 100644
index 0000000000..cf27105190
--- /dev/null
+++ b/addons/repair/functions/fnc_useItems.sqf
@@ -0,0 +1,39 @@
+/*
+ * Author: Glowbal
+ * Use Equipment items if any is available.
+ *
+ * Arguments:
+ * 0: Engineer <OBJECT>
+ * 1: Items <ARRAY<STRING>>
+ *
+ * ReturnValue:
+ * <NIL>
+ *
+ * Public: Yes
+ */
+
+#include "script_component.hpp"
+
+params ["_engineer", "_items"];
+TRACE_2("params",_engineer,_items);
+
+private ["_itemUsedInfo", "_itemsUsedBy"];
+
+_itemsUsedBy = [];
+{
+    // handle a one of type use item
+    if (typeName _x == "ARRAY") then {
+        {
+            _itemUsedInfo = [_engineer, _x] call FUNC(useItem);
+            if (_itemUsedInfo select 0) exitwith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]};
+        } forEach _x;
+    };
+
+    // handle required item
+    if (typeName _x == "STRING") then {
+        _itemUsedInfo = [_engineer, _x] call FUNC(useItem);
+        if (_itemUsedInfo select 0) exitwith { _itemsUsedBy pushback [(_itemUsedInfo select 1), _x]};
+    };
+} forEach _items;
+
+[count _items == count _itemsUsedBy, _itemsUsedBy];
diff --git a/addons/repair/functions/script_component.hpp b/addons/repair/functions/script_component.hpp
new file mode 100644
index 0000000000..ea8f8ef9f9
--- /dev/null
+++ b/addons/repair/functions/script_component.hpp
@@ -0,0 +1 @@
+#include "\z\ace\addons\repair\script_component.hpp"
\ No newline at end of file
diff --git a/addons/repair/script_component.hpp b/addons/repair/script_component.hpp
new file mode 100644
index 0000000000..23c52bdec8
--- /dev/null
+++ b/addons/repair/script_component.hpp
@@ -0,0 +1,16 @@
+#define COMPONENT repair
+#include "\z\ace\addons\main\script_mod.hpp"
+
+#ifdef DEBUG_ENABLED_REPAIR
+    #define DEBUG_MODE_FULL
+#endif
+
+#ifdef DEBUG_SETTINGS_REPAIR
+    #define DEBUG_SETTINGS DEBUG_SETTINGS_REPAIR
+#endif
+
+#include "\z\ace\addons\main\script_macros.hpp"
+
+
+#define IGNORED_HITPOINTS ["HitGlass1","HitGlass2","HitGlass3","HitGlass4","HitGlass5","HitGlass6","HitGlass7","HitGlass8","HitGlass9","HitGlass10","HitGlass11","HitGlass12","HitGlass13","HitGlass14","HitGlass15","HitRGlass","HitLGlass"]
+// #define TRACK_HITPOINTS ["HitLTrack", "HitRTrack"];
diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml
new file mode 100644
index 0000000000..ffafc56683
--- /dev/null
+++ b/addons/repair/stringtable.xml
@@ -0,0 +1,642 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Edited with tabler - 2014-12-21 -->
+<Project name="ACE">
+    <Package name="repair">
+        <Key ID="STR_ACE_Repair_SpareTrack">
+            <English>Spare Track</English>
+            <German>Ersatzkette</German>
+            <Spanish>Cadena de repuesto</Spanish>
+            <French>Chenille de réserve</French>
+            <Polish>Zapasowa gąsienica</Polish>
+            <Czech>Náhradní pásy</Czech>
+            <Portuguese>Lagarta Reserva</Portuguese>
+            <Italian>Cingolo di scorta</Italian>
+            <Hungarian>Pót lánctalp</Hungarian>
+            <Russian>Запасная гусеница</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_SpareWheel">
+            <English>Spare Wheel</English>
+            <German>Ersatzreifen</German>
+            <Spanish>Rueda de repuesto</Spanish>
+            <French>Roue de secours</French>
+            <Polish>Zapasowe koło</Polish>
+            <Czech>Náhradní Kolo</Czech>
+            <Portuguese>Roda Reserva</Portuguese>
+            <Italian>Ruota di scorta</Italian>
+            <Hungarian>Pótkerék</Hungarian>
+            <Russian>Запасное колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_ReplaceWheel">
+            <English>Change Wheel</English>
+            <German>Reifen wechseln</German>
+            <Spanish>Cambiar rueda</Spanish>
+            <French>Changer Roue</French>
+            <Polish>Wymień koło</Polish>
+            <Czech>Vyměňit kolo</Czech>
+            <Portuguese>Trocar Roda</Portuguese>
+            <Italian>Sostituisci la ruota</Italian>
+            <Hungarian>Kerék cseréje</Hungarian>
+            <Russian>Поменять колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_ReplacingWheel">
+            <English>Replacing Wheel ...</English>
+            <German>Ersetze Reifen ...</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_ReplacedWheel">
+            <English>Wheel replaced</English>
+            <German>Reifen ersetzt</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_RemoveWheel">
+            <English>Remove Wheel</English>
+            <German>Reifen entfernen</German>
+            <Spanish>Quitar rueda</Spanish>
+            <French>Démonter Roue</French>
+            <Polish>Zdejmij koło</Polish>
+            <Czech>Odstranit Kolo</Czech>
+            <Portuguese>Remover Roda</Portuguese>
+            <Italian>Rimuovi la ruota</Italian>
+            <Hungarian>Kerék leszerelése</Hungarian>
+            <Russian>Снять колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_RemovingWheel">
+            <English>Removing Wheel ...</English>
+            <German>Entferne Reifen ...</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_RemovedWheel">
+            <English>Wheel removed</English>
+            <German>Reifen entfernt</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_ReplaceTrack">
+            <English>Change Track</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_ReplacingTrack">
+            <English>Replacing Track ...</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_ReplacedTrack">
+            <English>Track replaced</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_RemoveTrack">
+            <English>Remove Track</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_RemovingTrack">
+            <English>Removing Track ...</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_RemovedTrack">
+            <English>Track removed</English>
+        </Key>
+
+        <Key ID="STR_ACE_Repair_fullRepair">
+            <English>Full Repair</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_fullyRepairing">
+            <English>Repairing Vehicle ...</English>
+        </Key>
+
+        <Key ID="STR_ACE_Repair_fullRepairLocation">
+            <English>Full Repair Locations</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_fullRepairLocation_description">
+            <English>At what locations can a vehicle be fully repaired?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_engineerSetting_fullRepair_name">
+            <English>Allow Full Repair</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_engineerSetting_fullRepair_description">
+            <English>Who can perform a full repair on a vehicle?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_RepairHitpoint">
+            <English>Repair %1</English>
+            <German>Reparieren %1</German>
+            <Spanish>Reparación %1</Spanish>
+            <French>Réparer %1</French>
+            <Polish>Napraw %1</Polish>
+            <Czech>Opravit %1</Czech>
+            <Portuguese>Reparar %1</Portuguese>
+            <Italian>Ripara %1</Italian>
+            <Hungarian>Szerelés %1</Hungarian>
+            <Russian>Ремонт %1</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_Repair">
+            <English>Repair &gt;&gt;</English>
+            <German>Reparieren &gt;&gt;</German>
+            <Spanish>Reparación &gt;&gt;</Spanish>
+            <French>Réparer &gt;&gt;</French>
+            <Polish>Napraw &gt;&gt;</Polish>
+            <Czech>Opravit &gt;&gt;</Czech>
+            <Portuguese>Reparar &gt;&gt;</Portuguese>
+            <Italian>Ripara &gt;&gt;</Italian>
+            <Hungarian>Szerelés &gt;&gt;</Hungarian>
+            <Russian>Ремонт &gt;&gt;</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_SettingDisplayTextName">
+            <English>Display text on repair</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_SettingDisplayTextDesc">
+            <English>Display a notification whenever you repair a vehicle</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_Repairing">
+            <English>Repairing ...</English>
+            <German>Reparieren ...</German>
+            <Spanish>Reparando ...</Spanish>
+            <French>Réparation ...</French>
+            <Polish>Naprawianie...</Polish>
+            <Czech>Opravuji ...</Czech>
+            <Portuguese>Reparando ...</Portuguese>
+            <Italian>Sto riparando ...</Italian>
+            <Hungarian>javítása ...</Hungarian>
+            <Russian>Ремонтируем ...</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_RepairingHitPoint">
+            <English>Repairing %1 ...</English>
+            <German>Reparieren %1 ...</German>
+            <Spanish>Reparando %1 ...</Spanish>
+            <French>Réparation %1 ...</French>
+            <Polish>Naprawianie %1...</Polish>
+            <Czech>Opravuji %1 ...</Czech>
+            <Portuguese>Reparando %1 ...</Portuguese>
+            <Italian>Sto riparando %1 ...</Italian>
+            <Hungarian>%1 javítása ...</Hungarian>
+            <Russian>Ремонтируем %1 ...</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_Repaired">
+            <English>Repaired %1</English>
+            <German>%1 repariert</German>
+            <Spanish>Reparado %1</Spanish>
+            <French>%1 réparé(e)</French>
+            <Polish>Naprawiono %1</Polish>
+            <Czech>Opraveno - %1</Czech>
+            <Portuguese>Reparado %1</Portuguese>
+            <Italian>%1 Riparata/o</Italian>
+            <Hungarian>%1 megjavítva</Hungarian>
+            <Russian>%1 отремонтирован</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_RepairedFully">
+            <English>Fully repaired part</English>
+            <German>Bauteil vollständig repariert</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_RepairedPartially">
+            <English>Partially repaired %1</English>
+            <German>Bauteil teilweise repariert</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_RepairedHitPointFully">
+            <English>Fully repaired %1</English>
+            <German>%1 vollständig repariert</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_RepairedHitPointPartially">
+            <English>Partially repaired %1</English>
+            <German>%1 teilweise repariert</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitBody">
+            <English>Body</English>
+            <German>Karosserie</German>
+            <Spanish>Carrocería</Spanish>
+            <French>Blindage</French>
+            <Polish>Karoseria</Polish>
+            <Czech>Karoserie</Czech>
+            <Portuguese>Carroceria</Portuguese>
+            <Italian>Carrozzeria</Italian>
+            <Hungarian>Test</Hungarian>
+            <Russian>Кузов</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitHull">
+            <English>Hull</English>
+            <German>Wanne</German>
+            <Spanish>Casco</Spanish>
+            <French>Caisse</French>
+            <Polish>Kadłub</Polish>
+            <Czech>Trup</Czech>
+            <Portuguese>Chassi</Portuguese>
+            <Italian>Scafo</Italian>
+            <Hungarian>Test</Hungarian>
+            <Russian>Корпус</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitEngine">
+            <English>Engine</English>
+            <German>Motor</German>
+            <Spanish>Motor</Spanish>
+            <French>Moteur</French>
+            <Polish>Silnik</Polish>
+            <Czech>Motor</Czech>
+            <Portuguese>Motor</Portuguese>
+            <Italian>Motore</Italian>
+            <Hungarian>Motor</Hungarian>
+            <Russian>Двигатель</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitFuel">
+            <English>Fuel Tank</English>
+            <German>Tank</German>
+            <Spanish>Depósito</Spanish>
+            <French>Réservoir</French>
+            <Polish>Zbiornik paliwa</Polish>
+            <Czech>Palivová nádrž</Czech>
+            <Portuguese>Tanque de Combustível</Portuguese>
+            <Italian>Serbatoio</Italian>
+            <Hungarian>Üzemanyagtank</Hungarian>
+            <Russian>Топливный бак</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitTurret">
+            <English>Main Turret</English>
+            <German>Turm</German>
+            <Spanish>Torreta príncipal</Spanish>
+            <French>Tourelle</French>
+            <Polish>Wieżyczka</Polish>
+            <Czech>Hlavní Věž</Czech>
+            <Portuguese>Torre principal</Portuguese>
+            <Italian>Torretta principale</Italian>
+            <Hungarian>Lövegtorony</Hungarian>
+            <Russian>Башню</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGun">
+            <English>Gun</English>
+            <German>Kanone</German>
+            <Spanish>Cañón</Spanish>
+            <French>Canon</French>
+            <Polish>Działo</Polish>
+            <Czech>Kanón</Czech>
+            <Portuguese>Canhão</Portuguese>
+            <Italian>Cannone</Italian>
+            <Hungarian>Ágyú</Hungarian>
+            <Russian>Пушку</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitLTrack">
+            <English>Left Track</English>
+            <German>Linke Kette</German>
+            <Spanish>Cadena izquierda</Spanish>
+            <French>Chenille gauche</French>
+            <Polish>Lewa gąsienica</Polish>
+            <Czech>Levý Pás</Czech>
+            <Portuguese>Lagarta Esquerda</Portuguese>
+            <Italian>Cingolo sinistro</Italian>
+            <Hungarian>Bal lánctalp</Hungarian>
+            <Russian>Левую гусеницу</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitRTrack">
+            <English>Right Track</English>
+            <German>Rechte Kette</German>
+            <Spanish>Cadena derecha</Spanish>
+            <French>Chenille droite</French>
+            <Polish>Prawa gąsienica</Polish>
+            <Czech>Pravý Pás</Czech>
+            <Portuguese>Lagarta Direita</Portuguese>
+            <Italian>Cingolo destro</Italian>
+            <Hungarian>Jobb lánctalp</Hungarian>
+            <Russian>Правую гусеницу</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitLFWheel">
+            <English>Left Front Wheel</English>
+            <German>Linkes Vorderrad</German>
+            <Spanish>Rueda frontal izquierda</Spanish>
+            <French>Roue avant-gauche</French>
+            <Polish>Przednie lewe koło</Polish>
+            <Czech>Levé přední Kolo</Czech>
+            <Portuguese>Roda Dianteira Esquerda</Portuguese>
+            <Italian>Ruota frontale sinistra</Italian>
+            <Hungarian>Bal első kerék</Hungarian>
+            <Russian>Левое переднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitRFWheel">
+            <English>Right Front Wheel</English>
+            <German>Rechtes Vorderrad</German>
+            <Spanish>Rueda frontal derecha</Spanish>
+            <French>Roue avant-droite</French>
+            <Polish>Przednie prawe koło</Polish>
+            <Czech>Pravé přední Kolo</Czech>
+            <Portuguese>Roda Dianteira Direita</Portuguese>
+            <Italian>Ruota frontale destra</Italian>
+            <Hungarian>Jobb első kerék</Hungarian>
+            <Russian>Правое переднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitLF2Wheel">
+            <English>Second Left Front Wheel</English>
+            <German>Zweites linkes Vorderrad</German>
+            <Spanish>Segunda rueda frontal izquierda</Spanish>
+            <French>Deuxième roue avant-gauche</French>
+            <Polish>Drugie przednie lewe koło</Polish>
+            <Czech>Druhé Levé přední Kolo</Czech>
+            <Portuguese>Segunda Roda Dianteira Esquerda</Portuguese>
+            <Italian>Seconda ruota frontale sinistra</Italian>
+            <Hungarian>Második bal első kerék</Hungarian>
+            <Russian>Второе переднее левое колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitRF2Wheel">
+            <English>Second Right Front Wheel</English>
+            <German>Zweites rechtes Vorderrad</German>
+            <Spanish>Segunda rueda frontal derecha</Spanish>
+            <French>Deuxième roue avant-droite</French>
+            <Polish>Drugie przednie prawe koło</Polish>
+            <Czech>Druhé Pravé přední Kolo</Czech>
+            <Portuguese>Segunda Roda Dianteira Direita</Portuguese>
+            <Italian>Seconda ruota frontale destra</Italian>
+            <Hungarian>Második jobb hátsó kerék</Hungarian>
+            <Russian>Второе правое переднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitLMWheel">
+            <English>Left Middle Wheel</English>
+            <German>Linkes mittleres Rad</German>
+            <Spanish>Rueda central izquierda</Spanish>
+            <French>Roue centre-gauche</French>
+            <Polish>Środkowe lewe koło</Polish>
+            <Czech>Levé prostřední Kolo</Czech>
+            <Portuguese>Roda Intermediária Esquerda</Portuguese>
+            <Italian>Ruota centrale sinistra</Italian>
+            <Hungarian>Bal középső kerék</Hungarian>
+            <Russian>Левое среднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitRMWheel">
+            <English>Right Middle Wheel</English>
+            <German>Rechtes mittleres Rad</German>
+            <Spanish>Rueda central derecha</Spanish>
+            <French>Roue centre-droite</French>
+            <Polish>Środkowe prawe koło</Polish>
+            <Czech>Pravé prostřední Kolo</Czech>
+            <Portuguese>Roda Intermediária Direita</Portuguese>
+            <Italian>Ruota centrale destra</Italian>
+            <Hungarian>Jobb középső kerék</Hungarian>
+            <Russian>Правое среднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitLBWheel">
+            <English>Left Rear Wheel</English>
+            <German>Linkes Hinterrad</German>
+            <Spanish>Rueda trasera izquierda</Spanish>
+            <French>Roue arrière-gauche</French>
+            <Polish>Tylnie lewe koło</Polish>
+            <Czech>Levé zadní Kolo</Czech>
+            <Portuguese>Roda Traseira Esquerda</Portuguese>
+            <Italian>Ruota posteriore sinistra</Italian>
+            <Hungarian>Bal hátsó kerék</Hungarian>
+            <Russian>Левое заднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitRBWheel">
+            <English>Right Rear Wheel</English>
+            <German>Rechtes Hinterrad</German>
+            <Spanish>Rueda trasera derecha</Spanish>
+            <French>Roue arrière-droite</French>
+            <Polish>Tylnie prawe koło</Polish>
+            <Czech>Pravé zadní Kolo</Czech>
+            <Portuguese>Roda Traseira Direita</Portuguese>
+            <Italian>Ruota posteriore destra</Italian>
+            <Hungarian>Jobb hátsó kerék</Hungarian>
+            <Russian>Правое заднее колесо</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitAvionics">
+            <English>Avionics</English>
+            <German>Avionik</German>
+            <Spanish>Aviónica</Spanish>
+            <French>Avionique</French>
+            <Polish>Awionika</Polish>
+            <Czech>Elektronika</Czech>
+            <Portuguese>Aviônica</Portuguese>
+            <Italian>Avionica</Italian>
+            <Hungarian>Avionika</Hungarian>
+            <Russian>Авионику</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitHRotor">
+            <English>Main Rotor</English>
+            <German>Hauptrotor</German>
+            <Spanish>Rotor principal</Spanish>
+            <French>Rotor principal</French>
+            <Polish>Główny rotor</Polish>
+            <Czech>Hlavní Rotor</Czech>
+            <Portuguese>Rotor Principal</Portuguese>
+            <Italian>Rotore principale</Italian>
+            <Hungarian>Főrotor</Hungarian>
+            <Russian>Несущий винт</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitVRotor">
+            <English>Tail Rotor</English>
+            <German>Heckrotor</German>
+            <Spanish>Rotor de cola</Spanish>
+            <French>Rotor anticouple</French>
+            <Polish>Tylni rotor</Polish>
+            <Czech>Zadní Rotor</Czech>
+            <Portuguese>Rotor de Cauda</Portuguese>
+            <Italian>Rotore di coda</Italian>
+            <Hungarian>Farokrotor</Hungarian>
+            <Russian>Рулевой винт</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitWinch">
+            <English>Winch</English>
+            <German>Seilwinde</German>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitRGlass">
+            <English>Glass (right)</English>
+            <German>Scheibe (rechts)</German>
+            <Spanish>Ventana (derecha)</Spanish>
+            <French>Vitre (droite)</French>
+            <Polish>Szyba (prawa)</Polish>
+            <Czech>Sklo (pravé)</Czech>
+            <Portuguese>Vidro (à direita)</Portuguese>
+            <Italian>Vetro destro</Italian>
+            <Hungarian>Jobb szélvédő</Hungarian>
+            <Russian>Стекло (справа)</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitLGlass">
+            <English>Glass (left)</English>
+            <German>Scheibe (links)</German>
+            <Spanish>Ventana (izquierda)</Spanish>
+            <French>Vitre (gauche)</French>
+            <Polish>Szyba (lewa)</Polish>
+            <Czech>Sklo (pravé)</Czech>
+            <Portuguese>Vidro (à esquerda)</Portuguese>
+            <Italian>Vetro sinistro</Italian>
+            <Hungarian>Bal szélvédő</Hungarian>
+            <Russian>Стекло (слава)</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGlass1">
+            <English>Glass 1</English>
+            <German>Scheibe 1</German>
+            <Spanish>Ventana 1</Spanish>
+            <French>Vitre 1</French>
+            <Polish>Szyba 1</Polish>
+            <Czech>Sklo 1</Czech>
+            <Portuguese>Vidro 1</Portuguese>
+            <Italian>Vetro 1</Italian>
+            <Hungarian>Üveg 1</Hungarian>
+            <Russian>Стекло 1</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGlass2">
+            <English>Glass 2</English>
+            <German>Scheibe 2</German>
+            <Spanish>Ventana 2</Spanish>
+            <French>Vitre 2</French>
+            <Polish>Szyba 2</Polish>
+            <Czech>Sklo 2</Czech>
+            <Portuguese>Vidro 2</Portuguese>
+            <Italian>Vetro 2</Italian>
+            <Hungarian>Üveg 2</Hungarian>
+            <Russian>Стекло 2</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGlass3">
+            <English>Glass 3</English>
+            <German>Scheibe 3</German>
+            <Spanish>Ventana 3</Spanish>
+            <French>Vitre 3</French>
+            <Polish>Szyba 3</Polish>
+            <Czech>Sklo 3</Czech>
+            <Portuguese>Vidro 3</Portuguese>
+            <Italian>Vetro 3</Italian>
+            <Hungarian>Üveg 3</Hungarian>
+            <Russian>Стекло 3</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGlass4">
+            <English>Glass 4</English>
+            <German>Scheibe 4</German>
+            <Spanish>Ventana 4</Spanish>
+            <French>Vitre 4</French>
+            <Polish>Szyba 4</Polish>
+            <Czech>Sklo 4</Czech>
+            <Portuguese>Vidro 4</Portuguese>
+            <Italian>Vetro 4</Italian>
+            <Hungarian>Üveg 4</Hungarian>
+            <Russian>Стекло 4</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGlass5">
+            <English>Glass 5</English>
+            <German>Scheibe 5</German>
+            <Spanish>Ventana 5</Spanish>
+            <French>Vitre 5</French>
+            <Polish>Szyba 5</Polish>
+            <Czech>Sklo 5</Czech>
+            <Portuguese>Vidro 5</Portuguese>
+            <Italian>Vetro 5</Italian>
+            <Hungarian>Üveg 5</Hungarian>
+            <Russian>Стекло 5</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_HitGlass6">
+            <English>Glass 6</English>
+            <German>Scheibe 6</German>
+            <Spanish>Ventana 6</Spanish>
+            <French>Vitre 6</French>
+            <Polish>Szyba 6</Polish>
+            <Czech>Sklo 6</Czech>
+            <Portuguese>Vidro 6</Portuguese>
+            <Italian>Vetro 6</Italian>
+            <Hungarian>Üveg 6</Hungarian>
+            <Russian>Стекло 6</Russian>
+        </Key>
+        <Key ID="STR_ACE_Repair_moduleName">
+            <English>Repair Settings</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_moduleDescription">
+            <English>Provides a repair system for all types of vehicles.</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_engineerSetting_anyone">
+            <English>Anyone</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_engineerSetting_EngineerOnly">
+            <English>Engineer only</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_engineerSetting_RepairSpecialistOnly">
+            <English>Repair Specialist only</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_enginerSetting_Wheel_name">
+            <English>Allow Wheel</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_enginerSetting_Wheel_description">
+            <English>Who can remove and replace wheels?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_enginerSetting_Repair_name">
+            <English>Allow Repair</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_enginerSetting_Repair_description">
+            <English>Who can perform repair actions?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_repairDamageThreshold_name">
+            <English>Repair Threshold</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_repairDamageThreshold_description">
+            <English>What is the maximum damage that can be repaired with a toolkit?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_repairDamageThreshold_Engineer_name">
+            <English>Repair Threshold (Engineer)</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_repairDamageThreshold_Engineer_description">
+            <English>What is the maximum damage that can be repaired by an engineer?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_consumeItem_ToolKit_name">
+            <English>Remove toolkit on use</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_consumeItem_ToolKit_description">
+            <English>Should the toolkit be removed on usage?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_useAnywhere">
+            <English>Anywhere</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_repairVehicleOnly">
+            <English>Repair Vehicle only</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_repairFacilityOnly">
+            <English>Repair Facility only</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_vehicleAndFacility">
+            <English>Repair Facility or Vehicle</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_Module_DisplayName">
+            <English>Assign Engineer</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_EnableList_DisplayName">
+            <English>List</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_EnableList_Description">
+            <English>List of unit names that will be classified as engineer, separated by commas.</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_role_DisplayName">
+            <English>Is Engineer</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_role_Description">
+            <English>Select the engineering skill level of the unit</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_role_none">
+            <English>None</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_role_engineer">
+            <English>Engineer</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_role_specialist">
+            <English>Specialist</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignEngineerRole_Module_Description">
+            <English>Assign one or multiple units as an engineer</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairVehicle_Module_DisplayName">
+            <English>Assign Repair Vehicle</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairVehicle_EnableList_DisplayName">
+            <English>List</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairVehicle_EnableList_Description">
+            <English>List of vehicles that will be classified as repair vehicle, separated by commas.</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairVehicle_role_DisplayName">
+            <English>Is Repair Vehicle</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairVehicle_role_Description">
+            <English>Is the vehicle classified as a repair vehicle?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairVehicle_Module_Description">
+            <English>Assign one or multiple vehicles as a repair vehicle</English>
+        </Key>
+
+        <Key ID="STR_ACE_Repair_AssignRepairFacility_Module_DisplayName">
+            <English>Assign Repair Facility</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairFacility_EnableList_DisplayName">
+            <English>List</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairFacility_EnableList_Description">
+            <English>List of objects that will be classified as repair Facility, separated by commas.</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairFacility_role_DisplayName">
+            <English>Is Repair Facility</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairFacility_role_Description">
+            <English>Is the object classified as a repair Facility?</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_AssignRepairFacility_Module_Description">
+            <English>Assign one or multiple objects as a repair Facility</English>
+        </Key>
+        <Key ID="STR_ACE_Repair_categoryName">
+            <English>Vehicle Repair</English>
+        </Key>
+    </Package>
+</Project>
diff --git a/addons/repair/ui/Icon_Module_Repair_ca.paa b/addons/repair/ui/Icon_Module_Repair_ca.paa
new file mode 100644
index 0000000000..11b0f896d6
Binary files /dev/null and b/addons/repair/ui/Icon_Module_Repair_ca.paa differ
diff --git a/addons/repair/ui/tire_ca.paa b/addons/repair/ui/tire_ca.paa
new file mode 100644
index 0000000000..93ceb6bb6c
Binary files /dev/null and b/addons/repair/ui/tire_ca.paa differ