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 >></English> + <German>Reparieren >></German> + <Spanish>Reparación >></Spanish> + <French>Réparer >></French> + <Polish>Napraw >></Polish> + <Czech>Opravit >></Czech> + <Portuguese>Reparar >></Portuguese> + <Italian>Ripara >></Italian> + <Hungarian>Szerelés >></Hungarian> + <Russian>Ремонт >></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