mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Fixes and improvements for the repair module
1. Added full repair, 2. Added missing settings to modules and settings framework, 3. added assign engineer module. 4. Fixed animation bug
This commit is contained in:
parent
0080335617
commit
83f46be990
@ -39,4 +39,19 @@ class ACE_Settings {
|
||||
value = 1;
|
||||
values[] = {ECSTRING(common,No), ECSTRING(common,Yes)};
|
||||
};
|
||||
|
||||
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)};
|
||||
};
|
||||
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)};
|
||||
};
|
||||
};
|
||||
|
@ -6,7 +6,7 @@ class ACE_Repair {
|
||||
|
||||
locations[] = {"All"};
|
||||
requiredEngineer = QGVAR(engineerSetting_Wheel);
|
||||
repairingTime = 5;
|
||||
repairingTime = 10;
|
||||
repairingTimeSelfCoef = 1;
|
||||
items[] = {"ToolKit"};
|
||||
condition = QUOTE(call FUNC(canReplaceWheel));
|
||||
@ -16,10 +16,10 @@ class ACE_Repair {
|
||||
callbackFailure = "";
|
||||
callbackProgress = "";
|
||||
|
||||
animationCaller = "AinvPknlMstpSlayWrflDnon_medicOther";
|
||||
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther";
|
||||
animationCallerSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic";
|
||||
animationCallerSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
|
||||
animationCaller = "Acts_carFixingWheel";
|
||||
animationCallerProne = "Acts_carFixingWheel";
|
||||
animationCallerSelf = "Acts_carFixingWheel";
|
||||
animationCallerSelfProne = "Acts_carFixingWheel";
|
||||
litter[] = {};
|
||||
};
|
||||
class RemoveWheel: ReplaceWheel {
|
||||
@ -33,6 +33,7 @@ class ACE_Repair {
|
||||
displayNameProgress = CSTRING(RepairingHitPoint);
|
||||
condition = QUOTE((_target getHitPointDamage _hitPoint) > ([_caller] call FUNC(getPostRepairDamage)));
|
||||
requiredEngineer = 0;
|
||||
repairingTime = 15;
|
||||
callbackSuccess = QUOTE(call FUNC(doRepair));
|
||||
};
|
||||
class RepairTrack: MiscRepair {
|
||||
@ -40,18 +41,30 @@ class ACE_Repair {
|
||||
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));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -70,6 +70,28 @@ class CfgVehicles {
|
||||
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);
|
||||
@ -77,6 +99,53 @@ class CfgVehicles {
|
||||
};
|
||||
};
|
||||
|
||||
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 LandVehicle;
|
||||
class Car: LandVehicle {
|
||||
MACRO_REPAIRVEHICLE
|
||||
|
@ -12,6 +12,7 @@ PREP(canReplaceTrack);
|
||||
PREP(doRemoveWheel);
|
||||
PREP(doRemoveTrack);
|
||||
PREP(doRepair);
|
||||
PREP(doFullRepair);
|
||||
PREP(doRepairTrack);
|
||||
PREP(doReplaceWheel);
|
||||
PREP(doReplaceTrack);
|
||||
@ -23,6 +24,7 @@ PREP(isInRepairFacility);
|
||||
PREP(isNearRepairVehicle);
|
||||
PREP(isRepairVehicle);
|
||||
PREP(moduleRepairSettings);
|
||||
PREP(moduleAssignEngineer);
|
||||
PREP(normalizeHitPoints);
|
||||
PREP(repair);
|
||||
PREP(repair_failure);
|
||||
|
@ -95,16 +95,7 @@ _wheelHitPointSelections = _wheelHitPointsWithSelections select 1;
|
||||
_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)};
|
||||
|
||||
// impossible to remove tracks
|
||||
if (_x in TRACK_HITPOINTS) then {
|
||||
/*//_selection = getText(configFile >> "CfgVehicles" >> _type >> "HitPoints" >> _x >> "name"); // TODO this is a valid selection, it's just on the wrong position.
|
||||
private "_action";
|
||||
_action = [_name, localize LSTRING(RemoveTrack), _icon, _statement, _condition, {}, [_x, "RemoveTrack"], _selection, 4] call EFUNC(interact_menu,createAction);
|
||||
[_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass);
|
||||
|
||||
_action = [_name, localize LSTRING(ReplaceTrack), _icon, _statement, _condition, {}, [_x, "ReplaceTrack"], _selection, 4] call EFUNC(interact_menu,createAction);
|
||||
[_type, 0, ["ACE_MainActions", QGVAR(Repair)], _action] call EFUNC(interact_menu,addActionToClass);*/
|
||||
|
||||
if (_x == "HitLTrack") then {
|
||||
_selection = [-1.75, 0, -1.75];
|
||||
} else {
|
||||
@ -121,6 +112,12 @@ _wheelHitPointSelections = _wheelHitPointsWithSelections select 1;
|
||||
};
|
||||
} 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;
|
||||
|
||||
|
@ -82,7 +82,7 @@ _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC
|
||||
case 0: {true};
|
||||
case 1: _repairVeh;
|
||||
case 2: _repairFacility;
|
||||
case 3: {call _repairFacility || call _repairVeh};
|
||||
case 3: {{call _repairFacility || call _repairVeh}};
|
||||
};
|
||||
_return = call _return;
|
||||
};
|
||||
|
17
addons/repair/functions/fnc_doFullRepair.sqf
Normal file
17
addons/repair/functions/fnc_doFullRepair.sqf
Normal file
@ -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;
|
@ -17,7 +17,10 @@ params ["_unit", ["_engineerN", 1]];
|
||||
TRACE_2("params",_unit,_engineerN);
|
||||
|
||||
private ["_class"];
|
||||
_class = _unit getVariable ["ACE_IsEngineer", getNumber (configFile >> "CfgVehicles" >> typeOf _unit >> "engineer")];
|
||||
|
||||
_class = _unit getVariable [QGVAR(engineerClass), 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));
|
||||
_class >= (_engineerN min GVAR(engineerSetting_Repair));
|
63
addons/repair/functions/fnc_moduleAssignEngineer.sqf
Normal file
63
addons/repair/functions/fnc_moduleAssignEngineer.sqf
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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"
|
||||
|
||||
private ["_logic","_setting","_objects", "_list", "_splittedList", "_nilCheckPassedList", "_parsedList"];
|
||||
_logic = [_this,0,objNull,[objNull]] call BIS_fnc_param;
|
||||
|
||||
if (!isNull _logic) then {
|
||||
_list = _logic getvariable ["EnableList",""];
|
||||
|
||||
_splittedList = [_list, ","] call BIS_fnc_splitString;
|
||||
_nilCheckPassedList = "";
|
||||
{
|
||||
_x = [_x] call EFUNC(common,stringRemoveWhiteSpace);
|
||||
if !(isnil _x) then {
|
||||
if (_nilCheckPassedList == "") then {
|
||||
_nilCheckPassedList = _x;
|
||||
} else {
|
||||
_nilCheckPassedList = _nilCheckPassedList + ","+ _x;
|
||||
};
|
||||
};
|
||||
}foreach _splittedList;
|
||||
|
||||
_list = "[" + _nilCheckPassedList + "]";
|
||||
_parsedList = [] call compile _list;
|
||||
_setting = _logic getvariable ["role",0];
|
||||
_objects = synchronizedObjects _logic;
|
||||
if (!(_objects isEqualTo []) && _parsedList isEqualTo []) then {
|
||||
{
|
||||
if (!isnil "_x") then {
|
||||
if (typeName _x == typeName objNull) then {
|
||||
if (local _x) then {
|
||||
_x setvariable ["ACE_IsEngineer", _setting, true];
|
||||
};
|
||||
};
|
||||
};
|
||||
}foreach _objects;
|
||||
};
|
||||
{
|
||||
if (!isnil "_x") then {
|
||||
if (typeName _x == typeName objNull) then {
|
||||
if (local _x) then {
|
||||
_x setvariable ["ACE_IsEngineer", _setting, true];
|
||||
};
|
||||
};
|
||||
};
|
||||
}foreach _parsedList;
|
||||
};
|
||||
|
||||
true
|
@ -22,4 +22,8 @@ if (!isServer) exitWith {};
|
||||
[_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.";
|
||||
|
@ -80,7 +80,7 @@ _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC
|
||||
case 0: {true};
|
||||
case 1: _repairVeh;
|
||||
case 2: _repairFacility;
|
||||
case 3: {call _repairFacility || call _repairVeh};
|
||||
case 3: {{call _repairFacility || call _repairVeh}};
|
||||
};
|
||||
_return = call _return;
|
||||
};
|
||||
@ -167,6 +167,8 @@ _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
|
||||
|
@ -26,11 +26,11 @@ if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
|
||||
_caller removeWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
if (vehicle _caller == _caller) then {
|
||||
[_caller, _caller getvariable [QGVAR(repairPrevAnimCaller), ""], 1] call EFUNC(common,doAnimation);
|
||||
[_caller, _caller getvariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation);
|
||||
};
|
||||
_caller setvariable [QGVAR(repairPrevAnimCaller), nil];
|
||||
|
||||
_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnTreatment), ""]);
|
||||
_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnrepair), ""]);
|
||||
if (_weaponSelect != "") then {
|
||||
_caller selectWeapon _weaponSelect;
|
||||
} else {
|
||||
|
@ -27,11 +27,11 @@ if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
|
||||
_caller removeWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
if (vehicle _caller == _caller) then {
|
||||
[_caller, _caller getvariable [QGVAR(repairPrevAnimCaller), ""], 1] call EFUNC(common,doAnimation);
|
||||
[_caller, _caller getvariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation);
|
||||
};
|
||||
_caller setvariable [QGVAR(repairPrevAnimCaller), nil];
|
||||
|
||||
_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnTreatment), ""]);
|
||||
_weaponSelect = (_caller getvariable [QGVAR(selectedWeaponOnrepair), ""]);
|
||||
if (_weaponSelect != "") then {
|
||||
_caller selectWeapon _weaponSelect;
|
||||
} else {
|
||||
|
@ -84,6 +84,26 @@
|
||||
<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>
|
||||
@ -519,7 +539,7 @@
|
||||
<English>Allow Repair</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Repair_enginerSetting_Repair_description">
|
||||
<English>Who can use the toolkit to fully repair?</English>
|
||||
<English>Who can perform repair actions?</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Repair_repairDamageThreshold_name">
|
||||
<English>Repair Threshold</English>
|
||||
@ -539,5 +559,44 @@
|
||||
<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>
|
||||
</Package>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user