From c7e13ca4c7106ffb567b84b8590a472df4cab2f1 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Mon, 3 Jul 2023 16:00:46 +0300 Subject: [PATCH 1/6] Repair - Move to separate settings menu (#9236) * Repair - Move from logistics settings menu * Repair - Move from logistics settings menu --- addons/repair/initSettings.sqf | 40 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/addons/repair/initSettings.sqf b/addons/repair/initSettings.sqf index 82a411c91d..554a666130 100644 --- a/addons/repair/initSettings.sqf +++ b/addons/repair/initSettings.sqf @@ -1,7 +1,9 @@ +private _category = format ["ACE %1", LLSTRING(Repair)]; + [ QGVAR(displayTextOnRepair), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, true, // default value false, // isGlobal {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -10,7 +12,7 @@ [ QGVAR(engineerSetting_repair), "LIST", [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] true, // isGlobal {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -19,7 +21,7 @@ [ QGVAR(engineerSetting_wheel), "LIST", [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] true, // isGlobal {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -28,7 +30,7 @@ [ QGVAR(patchWheelEnabled), "LIST", [LSTRING(patchWheelEnabled_name), LSTRING(patchWheelEnabled_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[-1,0,1,2],["str_player_none", LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // default value true // isGlobal ] call CBA_fnc_addSetting; @@ -37,7 +39,7 @@ QGVAR(patchWheelRequiredItems), "LIST", [LSTRING(patchWheelRequiredItems_DisplayName), LSTRING(patchWheelRequiredItems_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 1], true ] call CBA_fnc_addSetting; @@ -46,7 +48,7 @@ QGVAR(patchWheelLocation), "LIST", [LSTRING(patchWheelLocation_DisplayName), LSTRING(patchWheelLocation_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[["ground", "vehicle"], ["vehicle"], ["ground"]], ["str_difficulty_any", LSTRING(patchWheelOnVehicle), LSTRING(patchWheelOnGround)], 0], true ] call CBA_fnc_addSetting; @@ -54,7 +56,7 @@ [ QGVAR(repairDamageThreshold), "SLIDER", [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [0,1,0.6,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] true, // isGlobal {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -63,7 +65,7 @@ [ QGVAR(repairDamageThreshold_engineer), "SLIDER", [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [0,1,0.4,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] true, // isGlobal {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -72,7 +74,7 @@ [ QGVAR(consumeItem_toolKit), "LIST", // fnc_repair expects number [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] true, // isGlobal {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -82,7 +84,7 @@ QGVAR(locationsBoostTraining), "CHECKBOX", [ELSTRING(common,LocationsBoostTraining_DisplayName), LSTRING(LocationsBoostTraining_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, false, true ] call CBA_fnc_addSetting; @@ -90,7 +92,7 @@ [ QGVAR(fullRepairLocation), "LIST", [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] true, // isGlobal {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -99,7 +101,7 @@ [ QGVAR(engineerSetting_fullRepair), "LIST", [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] true, // isGlobal {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -108,7 +110,7 @@ [ QGVAR(addSpareParts), "CHECKBOX", [LSTRING(addSpareParts_name), LSTRING(addSpareParts_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, true, // default value true, // isGlobal {[QGVAR(addSpareParts), _this] call EFUNC(common,cbaSettings_settingChanged)}, @@ -119,7 +121,7 @@ QGVAR(wheelRepairRequiredItems), "LIST", [LSTRING(WheelRepairRequiredItems_DisplayName), LSTRING(WheelRepairRequiredItems_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 0], true ] call CBA_fnc_addSetting; @@ -128,7 +130,7 @@ QGVAR(miscRepairRequiredItems), "LIST", [LSTRING(MiscRepairRequiredItems_DisplayName), LSTRING(MiscRepairRequiredItems_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 1], true ] call CBA_fnc_addSetting; @@ -137,7 +139,7 @@ QGVAR(fullRepairRequiredItems), "LIST", [LSTRING(FullRepairRequiredItems_DisplayName), LSTRING(FullRepairRequiredItems_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [[[], [ANY_TOOLKIT_FAKECLASS]], ["STR_A3_None", "STR_A3_CfgWeapons_Toolkit0"], 1], true ] call CBA_fnc_addSetting; @@ -145,7 +147,7 @@ [ QGVAR(autoShutOffEngineWhenStartingRepair), "CHECKBOX", [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, false, // default value true, // isGlobal {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} @@ -156,7 +158,7 @@ QGVAR(patchWheelTime), "SLIDER", [LSTRING(patchWheelTime_DisplayName), LSTRING(patchWheelTime_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [0.1, 60, 5, 1], true ] call CBA_fnc_addSetting; @@ -165,7 +167,7 @@ QGVAR(patchWheelMaximumRepair), "SLIDER", [LSTRING(patchWheelMaximumRepair_DisplayName), LSTRING(patchWheelMaximumRepair_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_repair"], + _category, [0, 1, 0.3, 1, true], true ] call CBA_fnc_addSetting; From cc1636c14f3cf58e777e30e4a7fbaac02e9ae1e4 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Thu, 6 Jul 2023 06:51:00 +0300 Subject: [PATCH 2/6] Repair - Change Repair Threshold setting descriptions (#9242) * change stringtable * change setting to % slider * keep old translations --- addons/repair/initSettings.sqf | 4 ++-- addons/repair/stringtable.xml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/repair/initSettings.sqf b/addons/repair/initSettings.sqf index 554a666130..040e44c2eb 100644 --- a/addons/repair/initSettings.sqf +++ b/addons/repair/initSettings.sqf @@ -57,7 +57,7 @@ private _category = format ["ACE %1", LLSTRING(Repair)]; QGVAR(repairDamageThreshold), "SLIDER", [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], _category, - [0,1,0.6,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + [0, 1, 0.6, 1, true], true, // isGlobal {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; @@ -66,7 +66,7 @@ private _category = format ["ACE %1", LLSTRING(Repair)]; QGVAR(repairDamageThreshold_engineer), "SLIDER", [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], _category, - [0,1,0.4,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + [0, 1, 0.4, 1, true], true, // isGlobal {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 3b650f13d5..92bee905bb 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -1285,7 +1285,7 @@ 維修門檻 - What is the maximum damage that can be repaired with a toolkit? + Maximum damage to which a part can be repaired with a toolkit.\n0% means all damage can be repaired. Der maximale Schaden, der von einem Reperatursatz behoben werden kann? Jaki jest maksymalny poziom uszkodzeń jaki może zostać naprawiony przy pomocy narzędzi? Qual é o dano máximo que pode ser reparado com um kit de ferramentas? @@ -1315,7 +1315,7 @@ 維修門檻 (工兵) - What is the maximum damage that can be repaired by an engineer? + Maximum damage to which a part can be repaired by an engineer above the minimum level required for the repair.\n0% means all damage can be repaired. Der maximale Schaden, der von einem Pionier behoben werden kann? Jaki jest maksymalny poziom uszkodzeń jaki może zostać naprawiony przez mechanika? Qual é o dano máximo que pode ser reparado com um engenheiro? From 50430e47efab1ff4ecec6b9192f9290d383e4305 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Thu, 6 Jul 2023 06:51:25 +0300 Subject: [PATCH 3/6] Medical - Change Epinephrine Wake Up Boost setting description (#9240) * change stringtable * keep old translations --- addons/medical/stringtable.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index c76c312f89..4be9a4029f 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -65,7 +65,7 @@ 에피네프린 사용 시 추가 회복 확률 - Increases how often spontaneous wake up checks happen when patient has Epinephrine in their system. + When an unconscious patient has Epinephrine in their system, the time between spontaneous wake up checks is divided by this value. 患者がアドレナリンを投与されると自発的に覚醒する確率を上昇させます。 增加因病患的循環系統裡面的腎上腺素自我甦醒的機率。 增加因病患的循环系统里面的肾上腺素自我苏醒的机率。 From 04e41a4d5ad6227b33ac4a7286f782b19204ef3b Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Thu, 6 Jul 2023 06:52:04 +0300 Subject: [PATCH 4/6] Repair - Make Full Repair Time dependent on vehicle damage (#8417) * add variable full repair time * enable compile cache * Fix stupid * whoops * incremental full repair * cleanup function header * ignore hitpoints inFullRepairProgress * fix getHitPointsToIgnore * final cleanup * don't show repair hint while doing full repair * make this all work * fix stupid put this back in place * Add setting for speedup when near repair facility/vehicle enable compile cache * refactor near repair facility/vehicle checks * remove skipping hint from do_repair better for feedback this way * git diff stuff * use functions directly in ACE_Repair.hpp * add check for vehicle proximity * add a new line * switch to multiply by setting instead * speed boost settings, remove exit addRepairActions * stringtable * remove speed boost settings * fix things, add forceDisplayName * name in function header * fix TRACE * add animation looping * remove systemChat Co-authored-by: Filip Maciejewski * add time coefficient setting * move to repair category * time coefficient max and default values --------- Co-authored-by: Salluci <69561145+Salluci@users.noreply.github.com> Co-authored-by: Filip Maciejewski --- addons/repair/ACE_Repair.hpp | 13 +- addons/repair/XEH_PREP.hpp | 3 + .../repair/functions/fnc_addRepairActions.sqf | 62 +++----- addons/repair/functions/fnc_doRepair.sqf | 8 +- .../functions/fnc_fullRepairProgress.sqf | 50 ++++++ .../functions/fnc_getFullRepairTime.sqf | 42 ++++++ .../functions/fnc_getHitPointsToIgnore.sqf | 142 ++++++++++++++++++ .../functions/fnc_getPostRepairDamage.sqf | 9 +- .../functions/fnc_isInRepairFacility.sqf | 25 +-- .../functions/fnc_isNearRepairVehicle.sqf | 14 +- addons/repair/functions/fnc_repair.sqf | 23 ++- .../repair/functions/fnc_repair_failure.sqf | 4 + .../repair/functions/fnc_repair_success.sqf | 4 + addons/repair/initSettings.sqf | 23 +++ addons/repair/script_component.hpp | 4 + addons/repair/stringtable.xml | 26 +++- 16 files changed, 366 insertions(+), 86 deletions(-) create mode 100644 addons/repair/functions/fnc_fullRepairProgress.sqf create mode 100644 addons/repair/functions/fnc_getFullRepairTime.sqf create mode 100644 addons/repair/functions/fnc_getHitPointsToIgnore.sqf diff --git a/addons/repair/ACE_Repair.hpp b/addons/repair/ACE_Repair.hpp index ae436791ad..344c509b2f 100644 --- a/addons/repair/ACE_Repair.hpp +++ b/addons/repair/ACE_Repair.hpp @@ -3,10 +3,11 @@ class ACE_Repair { class ReplaceWheel { displayName = CSTRING(ReplaceWheel); displayNameProgress = CSTRING(ReplacingWheel); + forceDisplayName = 0; repairLocations[] = {"All"}; requiredEngineer = QGVAR(engineerSetting_Wheel); - repairingTime = 10; + repairingTime = QGVAR(wheelChangeTime); repairingTimeSelfCoef = 1; items = QGVAR(wheelRepairRequiredItems); condition = QFUNC(canReplaceWheel); @@ -21,6 +22,7 @@ class ACE_Repair { animationCallerProne = "Acts_carFixingWheel"; animationCallerSelf = "Acts_carFixingWheel"; animationCallerSelfProne = "Acts_carFixingWheel"; + loopAnimation = 0; litter[] = {}; }; class RemoveWheel: ReplaceWheel { @@ -46,7 +48,7 @@ class ACE_Repair { displayNameProgress = CSTRING(RepairingHitPoint); condition = QFUNC(canMiscRepair); requiredEngineer = QGVAR(engineerSetting_Repair); - repairingTime = 15; + repairingTime = QGVAR(miscRepairTime); callbackSuccess = QFUNC(doRepair); items = QGVAR(miscRepairRequiredItems); itemConsumed = QGVAR(consumeItem_ToolKit); @@ -80,11 +82,14 @@ class ACE_Repair { class FullRepair: MiscRepair { displayName = CSTRING(fullRepair); displayNameProgress = CSTRING(fullyRepairing); + forceDisplayName = 1; + loopAnimation = 1; requiredEngineer = QGVAR(engineerSetting_fullRepair); repairLocations[] = {QGVAR(fullRepairLocation)}; - repairingTime = 30; - condition = "-1 != ((getAllHitPointsDamage _target param [2,[]]) findIf {_x > 0})"; + repairingTime = QFUNC(getFullRepairTime); + condition = "((getAllHitPointsDamage _target) select 2) findIf {_x > 0} != -1"; callbackSuccess = QFUNC(doFullRepair); + callbackProgress = QFUNC(fullRepairProgress); items = QGVAR(fullRepairRequiredItems); itemConsumed = QGVAR(consumeItem_ToolKit); }; diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 7c82632f87..ea9e40a4e7 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -17,8 +17,11 @@ PREP(doRepair); PREP(doRepairTrack); PREP(doReplaceTrack); PREP(doReplaceWheel); +PREP(fullRepairProgress); PREP(getClaimObjects); +PREP(getFullRepairTime); PREP(getHitPointString); +PREP(getHitPointsToIgnore); PREP(getPatchWheelTime); PREP(getPostRepairDamage); PREP(getRepairItems); diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index f78863985d..20607ca940 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -25,6 +25,9 @@ TRACE_2("addRepairActions", _vehicle,_type); private _initializedClasses = GETMVAR(GVAR(initializedClasses),[]); if (_type in _initializedClasses) exitWith {}; +// get hitPoints to ignore +private _hitPointsToIgnore = [_vehicle] call FUNC(getHitPointsToIgnore); + // get all hitpoints and selections (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case @@ -40,8 +43,6 @@ private _icon = ["a3\ui_f\data\igui\cfg\actions\repair_ca.paa", "#FFFFFF"]; private _vehCfg = configOf _vehicle; // Custom position can be defined via config for associated hitpoint private _hitpointPositions = getArray (_vehCfg >> QGVAR(hitpointPositions)); -// Associated hitpoints can be grouped via config to produce a single repair action -private _hitpointGroups = getArray (_vehCfg >> QGVAR(hitpointGroups)); // Get turret paths private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehicle, "commander", true])) apply {_x # 3}; @@ -88,59 +89,32 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi _processedSelections pushBack _selection; } else { - // Empty hitpoints don't contain enough information - if (_hitpoint isEqualTo "") exitWith { TRACE_3("Skipping Empty Hit",_hitpoint,_forEachIndex,_selection); }; - // Ignore glass hitpoints - if ((_hitpoint find "glass") != -1) exitWith { TRACE_3("Skipping Glass",_hitpoint,_forEachIndex,_selection); }; - // Ignore hitpoints starting with # (seems to be lights) - if ((_hitpoint select [0,1]) == "#") exitWith { TRACE_3("Skipping # hit",_hitpoint,_forEachIndex,_selection); }; - // Ignore ERA/Slat armor (vanilla uses hitera_/hitslat_, pre-1.82 RHS uses era_) - // ToDo: see how community utilizes new armor system, could also check getText (_hitpointConfig >> "simulation") - if (((_hitpoint select [0,7]) == "hitera_") || {(_hitpoint select [0,8]) == "hitslat_"} || {(_hitpoint select [0,4]) == "era_"}) exitWith { TRACE_3("Skipping ERA/SLAT",_hitpoint,_forEachIndex,_selection); }; + // Skip ignored hitpoints + if (_hitpoint in _hitPointsToIgnore) exitWith { + TRACE_3("Skipping ignored hitpoint",_hitpoint,_forEachIndex,_selection); + }; // Some hitpoints do not have a selection but do have an armorComponent value (seems to mainly be RHS) // Ref https://community.bistudio.com/wiki/Arma_3_Damage_Enhancement // this code won't support identically named hitpoints (e.g. commander turret: Duplicate HitPoint name 'HitTurret') private _armorComponent = ""; if (_selection == "") then { - { - private _turretHitpointCfg = ([_vehCfg, _x] call CBA_fnc_getTurret) >> "HitPoints"; - private _hitpointsCfg = "configName _x == _hitpoint" configClasses _turretHitpointCfg; - if (_hitpointsCfg isNotEqualTo []) exitWith { - TRACE_2("turret hitpoint configFound",_hitpoint,_x); - // only do turret hitpoints or stuff linked to visuals for now or we apparently get some weird stuff - if ((_hitpoint in ["hitturret", "hitgun"]) || {(getNumber (_hitpointsCfg # 0 >> "isGun")) == 1} || {(getNumber (_hitpointsCfg # 0 >> "isTurret")) == 1} || {(getText (_hitpointsCfg # 0 >> "visual")) != ""}) then { + private _hitpointsCfg = "configName _x == _hitpoint" configClasses (_vehCfg >> "HitPoints"); + if (_hitpointsCfg isNotEqualTo []) then { + _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); + }; + if (_armorComponent == "") then { + { + private _turretHitpointCfg = ([_vehCfg, _x] call CBA_fnc_getTurret) >> "HitPoints"; + private _hitpointsCfg = "configName _x == _hitpoint" configClasses _turretHitpointCfg; + if (_hitpointsCfg isNotEqualTo []) exitWith { + TRACE_2("turret hitpoint configFound",_hitpoint,_x); _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); }; - }; - } forEach _turretPaths; - if (_armorComponent == "") then { - private _hitpointsCfg = "configName _x == _hitpoint" configClasses (_vehCfg >> "HitPoints"); - if ((getText (_hitpointsCfg # 0 >> "visual")) != "") then { - _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); - }; + } forEach _turretPaths; }; if (_armorComponent != "") then { INFO_3("%1: %2 no selection: using armorComponent %3",_type,_hitpoint,_armorComponent); }; }; - if ((_selection == "") && {_armorComponent == ""}) exitWith { TRACE_3("Skipping no selection OR armor component",_hitpoint,_forEachIndex,_selection); }; - - - //Depends hitpoints shouldn't be modified directly (will be normalized) - // Biki: Clearing 'depends' in case of inheritance cannot be an empty string (rpt warnings), but rather a "0" value. - if (!((getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) exitWith { - TRACE_3("Skip Depends",_hitpoint,_forEachIndex,_selection); - }; - - private _childHitPoint = false; - { - { - if (_hitpoint == _x) exitWith { - _childHitPoint = true; - }; - } forEach (_x select 1); - } forEach _hitpointGroups; - // If the current selection is associated with a child hitpoint, then skip - if (_childHitPoint) exitWith { TRACE_3("childHitpoint",_hitpoint,_forEachIndex,_selection); }; // Find the action position private _position = compile format ["_target selectionPosition ['%1', 'HitPoints'];", _selection]; diff --git a/addons/repair/functions/fnc_doRepair.sqf b/addons/repair/functions/fnc_doRepair.sqf index 1b6f497d8e..2874eaf2f8 100644 --- a/addons/repair/functions/fnc_doRepair.sqf +++ b/addons/repair/functions/fnc_doRepair.sqf @@ -7,6 +7,7 @@ * 0: Unit that does the repairing * 1: Vehicle to repair * 2: Selected hitpointIndex + * 3: Repair action classname * * Return Value: * None @@ -17,10 +18,11 @@ * Public: No */ -params ["_unit", "_vehicle", "_hitPointIndex"]; -TRACE_3("params",_unit,_vehicle,_hitPointIndex); +params ["_unit", "_vehicle", "_hitPointIndex", "_action"]; +TRACE_4("params",_unit,_vehicle,_hitPointIndex,_action); -private _postRepairDamageMin = [_unit] call FUNC(getPostRepairDamage); +// override minimum damage if doing full repair +private _postRepairDamageMin = [_unit, _action isEqualTo "fullRepair"] call FUNC(getPostRepairDamage); (getAllHitPointsDamage _vehicle) params ["_allHitPoints"]; private _hitPointClassname = _allHitPoints select _hitPointIndex; diff --git a/addons/repair/functions/fnc_fullRepairProgress.sqf b/addons/repair/functions/fnc_fullRepairProgress.sqf new file mode 100644 index 0000000000..444bb750b3 --- /dev/null +++ b/addons/repair/functions/fnc_fullRepairProgress.sqf @@ -0,0 +1,50 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Handles full repair by periodically repairing damaged hitpoints. + * + * Arguments: + * 0: Arguments + * 0: Engineer + * 1: Vehicle + * 2: Hitpoint (unused) + * 3: Repair action classname + * 1: Elapsed Time + * 2: Total Time + * + * Return Value: + * Continue Repair + * + * Example: + * [[objNull, player], 5, 10] call ace_repair_fnc_fullRepairProgress + * + * Public: No + */ + +params ["_args", "_elapsedTime", "_totalTime"]; +_args params ["_engineer", "_vehicle", "", "_action"]; + +if !((alive _vehicle) && {(abs speed _vehicle) < 1}) exitWith {false}; // make sure vehicle doesn't drive off + +// Not enough time has elapsed to repair a hitpoint +if (_totalTime - _elapsedTime > ([_engineer, _vehicle] call FUNC(getFullRepairTime)) - (GVAR(miscRepairTime) * GVAR(timeCoefficientFullRepair))) exitWith {true}; + +private _allHitPointsDamage = getAllHitPointsDamage _vehicle; +_allHitPointsDamage params ["_hitPoints", "", "_damageValues"]; + +private _hitPointsToIgnore = [_vehicle] call FUNC(getHitPointsToIgnore); + +private _firstDamagedIndex = { + private _hitPoint = _hitPoints select _forEachIndex; + if (_x > 0 && {!(_hitPoint in _hitPointsToIgnore)}) exitWith {_forEachIndex}; + -1 +} forEach _damageValues; + +// Stop repairing if there are no more damaged hitpoints +// callBackSuccess to FUNC(doFullRepair) for ignored hitpoints +if (_firstDamagedIndex == -1) exitWith {true}; + +// Repair the first damaged hitpoint +[_engineer, _vehicle, _firstDamagedIndex, _action] call FUNC(doRepair); + +true diff --git a/addons/repair/functions/fnc_getFullRepairTime.sqf b/addons/repair/functions/fnc_getFullRepairTime.sqf new file mode 100644 index 0000000000..78f46472a5 --- /dev/null +++ b/addons/repair/functions/fnc_getFullRepairTime.sqf @@ -0,0 +1,42 @@ +#include "script_component.hpp" +/* + * Author: LinkIsGrim + * Calculates the Full Repair time based on the amount of hitpoints to repair + * + * Arguments: + * 0: Engineer + * 1: Vehicle + * + * Return Value: + * Repair Time + * + * Example: + * [player, vehicle] call ace_repair_fnc_getFullRepairTime + * + * Public: No + */ + +params ["_engineer", "_vehicle"]; + +private _allHitPointsDamage = getAllHitPointsDamage _vehicle; +_allHitPointsDamage params ["_hitPoints", "", "_damageValues"]; + +private _hitPointsToIgnore = [_vehicle] call FUNC(getHitPointsToIgnore); + +private _repairsNeeded = 0; +private _doExtraRepair = false; +{ + if (_x <= 0) then {continue}; // skip hitpoints that don't need repairs + private _hitPoint = _hitPoints select _forEachIndex; + if (_hitPoint in _hitPointsToIgnore) then { // only add extra repair for ignore hitpoints if they're damaged + _doExtraRepair = true; + continue + }; + _repairsNeeded = _repairsNeeded + ceil (_x / 0.5); // repair is capped at 0.5 in FUNC(doRepair) +} forEach _damageValues; + +if (_doExtraRepair) then { + _repairsNeeded = _repairsNeeded + 1; +}; + +_repairsNeeded * GVAR(miscRepairTime) * GVAR(timeCoefficientFullRepair) // return diff --git a/addons/repair/functions/fnc_getHitPointsToIgnore.sqf b/addons/repair/functions/fnc_getHitPointsToIgnore.sqf new file mode 100644 index 0000000000..24f2d9a207 --- /dev/null +++ b/addons/repair/functions/fnc_getHitPointsToIgnore.sqf @@ -0,0 +1,142 @@ +#include "script_component.hpp" +/* + * Author: commy2, kymckay, LinkIsGrim + * Get list of vehicle hitpoints to ignore + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * HitPoints to ignore + * + * Example: + * [vehicle] call ace_repair_fnc_getHitpointsToIgnore + * + * Public: No + */ + +params ["_vehicle"]; + +private _type = typeOf _vehicle; +TRACE_2("getHitPointsToIgnore", _vehicle,_type); +private _initializedClasses = missionNamespace getVariable [QGVAR(hitPointsToIgnoreInitializedClasses), createHashMap]; +if (_type in _initializedClasses) exitWith {_initializedClasses get _type}; + +private _vehCfg = configOf _vehicle; +private _hitpointGroups = getArray (_vehCfg >> QGVAR(hitpointGroups)); +private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehicle, "commander", true])) apply {_x # 3}; + +(getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; +// get hitpoints of wheels with their selections +([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + +private _hitPointsToIgnore = [""]; // always ignore empty hitpoints +private _processedSelections = []; + +{ + private _selection = _x; + private _hitpoint = toLower (_hitPoints select _forEachIndex); + private _isWheelOrTrack = _selection in _wheelHitSelections || {_hitpoint in _wheelHitPoints} || {_hitpoint in TRACK_HITPOINTS}; + + if (_hitpoint isEqualTo "") then { // skip empty hitpoint + continue + }; + + if (_isWheelOrTrack && {_selection in _processedSelections || {_selection isEqualTo ""}}) then { // skip duplicate or empty selection wheel/track + TRACE_3("Skipping duplicate Wheel/Track or empty selection",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping duplicate wheel, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + if ("glass" in _hitpoint) then { // skip glass + TRACE_3("Skipping glass",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping glass, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + if (_hitpoint select [0,1] isEqualTo "#" || {_hitpoint select [0,9] isEqualTo "hit_light"}) then { // skip lights + TRACE_3("Skipping light",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping light, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + if (_hitpoint select [0,7] isEqualTo "hitera_" || {_hitpoint select [0,8] isEqualTo "hitslat_"} || {_hitpoint select [0,4] isEqualTo "era_"}) then { // skip era/slat + TRACE_3("Skipping ERA/Slat HitPoint",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping ERA/SLAT, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + private _armorComponent = ""; + if (_selection == "") then { // some hitpoints have empty selection but defined armor component (mostly RHS) + { + private _turretHitpointCfg = ([_vehCfg, _x] call CBA_fnc_getTurret) >> "HitPoints"; + private _hitpointsCfg = "configName _x == _hitpoint" configClasses _turretHitpointCfg; + if (_hitpointsCfg isNotEqualTo []) exitWith { + TRACE_2("turret hitpoint configFound",_hitpoint,_x); + // only do turret hitpoints and stuff linked to visuals + if ((_hitpoint in ["hitturret", "hitgun"]) || {(getNumber (_hitpointsCfg # 0 >> "isGun")) == 1} || {(getNumber (_hitpointsCfg # 0 >> "isTurret")) == 1} || {(getText (_hitpointsCfg # 0 >> "visual")) != ""}) then { + _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); + }; + }; + } forEach _turretPaths; + if (_armorComponent == "") then { + private _hitpointsCfg = "configName _x == _hitpoint" configClasses (_vehCfg >> "HitPoints"); + if (_hitpointsCfg isNotEqualTo [] && {(getText (_hitpointsCfg # 0 >> "visual")) != ""}) then { + _armorComponent = getText (_hitpointsCfg # 0 >> "armorComponent"); + }; + }; + }; + + if ((_selection == "") && {_armorComponent == ""}) then { + TRACE_3("Skipping no selection OR armor component",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping no selection OR armor component, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + if (!(getText (_vehCfg >> "HitPoints" >> _hitpoint >> "depends") in ["", "0"])) then { // skip depends hitpoints, should be normalized by engine + TRACE_3("Skipping depends hitpoint",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping depends hitpoint, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + if ((_hitpointGroups findIf {(_x select 1) == _hitpoint}) != -1) then { // skip child hitpoints + TRACE_3("Skipping child hitpoint",_hitpoint,_forEachIndex,_selection); + /*#ifdef DEBUG_MODE_FULL + systemChat format ["Skipping child hitpoint, hitpoint %1, index %2, selection %3", _hitpoint, _forEachIndex, _selection]; + #endif*/ + _hitPointsToIgnore pushBackUnique _hitpoint; + _processedSelections pushBack _selection; + continue + }; + + _processedSelections pushBack _selection; +} forEach _hitSelections; + +_initializedClasses set [_type, _hitPointsToIgnore]; +missionNamespace setVariable [QGVAR(hitPointsToIgnoreInitializedClasses), _initializedClasses]; + +_hitPointsToIgnore diff --git a/addons/repair/functions/fnc_getPostRepairDamage.sqf b/addons/repair/functions/fnc_getPostRepairDamage.sqf index 0eac151e45..141df15369 100644 --- a/addons/repair/functions/fnc_getPostRepairDamage.sqf +++ b/addons/repair/functions/fnc_getPostRepairDamage.sqf @@ -5,6 +5,7 @@ * * Arguments: * 0: Unit that does the repairing + * 1: Override for full repair (default: false) * * Return Value: * 0: Repair Damage Threshold @@ -15,11 +16,11 @@ * Public: No */ -params ["_unit"]; -TRACE_1("params",_unit); +params ["_unit", ["_override", false]]; +TRACE_2("params",_unit,_override); -//If in facility or near vehicle then complete repair of hitpoint: -if (([_unit] call FUNC(isInRepairFacility) || {[_unit] call FUNC(isNearRepairVehicle)})) exitWith {0}; +//If in facility, near vehicle, or doing full repair then complete repair of hitpoint: +if ((_override || {[_unit] call FUNC(isInRepairFacility)} || {[_unit] call FUNC(isNearRepairVehicle)})) exitWith {0}; private _class = _unit getVariable ["ACE_IsEngineer", getNumber (configOf _unit >> "engineer")]; //If advanced or more qualified than min, then use engineer threshold: diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index 1693297494..a0a1615cd9 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -15,28 +15,15 @@ * Public: Yes */ +#define CHECK_OBJECTS(var) ((var) findIf {(_x getVariable ["ACE_isRepairFacility", getNumber (configOf _x >> QGVAR(canRepair))] > 0) && {!(_x isKindOf "AllVehicles")} && {alive _x}} != -1) + params [["_object", objNull, [objNull]]]; TRACE_1("params",_object); -private _position = getPosASL _object; -private _isInBuilding = false; -private _checkObject = { - if ( - _x getVariable ["ACE_isRepairFacility", getNumber (configOf _x >> QGVAR(canRepair))] > 0 - && {!(_x isKindOf "AllVehicles")} // check if it's not repair vehicle - && {alive _x} - ) exitWith { - _isInBuilding = true; - }; +private _fnc_check = { + private _position = _object modelToWorldVisual [0, 0, eyePos _object select 2]; + CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position, _position vectorAdd [ARR_3(0, 0, 10)], _object)]) || {CHECK_OBJECTS(_object nearObjects 7.5)} }; -private _objects = (lineIntersectsWith [_object modelToWorldVisual [0, 0, (_position select 2)], _object modelToWorldVisual [0, 0, (_position select 2) +10], _object]); -_checkObject forEach _objects; - -if (_isInBuilding) exitWith {true}; - -_objects = _object nearObjects 7.5; -_checkObject forEach _objects; - -_isInBuilding +[[], _fnc_check, _object, QGVAR(inRepairFacilityCache), IN_REPAIR_FACILITY_CACHE_EXPIRY] call EFUNC(common,cachedCall); diff --git a/addons/repair/functions/fnc_isNearRepairVehicle.sqf b/addons/repair/functions/fnc_isNearRepairVehicle.sqf index 1243c0f95b..3a894162ee 100644 --- a/addons/repair/functions/fnc_isNearRepairVehicle.sqf +++ b/addons/repair/functions/fnc_isNearRepairVehicle.sqf @@ -15,14 +15,14 @@ * Public: Yes */ +#define CHECK_OBJECTS(var) ((var) findIf {alive _x && {[_x] call FUNC(isRepairVehicle)}} != -1) + params ["_unit"]; TRACE_1("params",_unit); -private _nearObjects = nearestObjects [_unit, ["Air", "LandVehicle", "Slingload_base_F"], 20]; +private _fnc_check = { + private _nearObjects = nearestObjects [_unit, ["Air", "LandVehicle", "Slingload_base_F"], 20]; + CHECK_OBJECTS(_nearObjects) +}; -private _return = false; -{ - if (alive _x && {[_x] call FUNC(isRepairVehicle)}) exitWith {_return = true;}; -} forEach _nearObjects; - -_return; +[[], _fnc_check, _unit, QGVAR(nearRepairVehicleCache), NEAR_REPAIR_VEHICLE_CACHE_EXPIRY] call EFUNC(common,cachedCall); diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index 51fdea90fe..a0654d2555 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -148,6 +148,7 @@ if (_callbackProgress == "") then { // Player Animation private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); +private _loopAnim = (getNumber (_config >> "loopAnimation")) isEqualTo 1; _caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller]; // Cannot use secondairy weapon for animation @@ -171,10 +172,27 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { } else { _caller setVariable [QGVAR(repairPrevAnimCaller), animationState _caller]; }; + _caller setVariable [QGVAR(repairCurrentAnimCaller), toLower _callerAnim]; [_caller, _callerAnim] call EFUNC(common,doAnimation); }; }; +if (_loopAnim) then { + private _animDoneEh = _caller addEventHandler ["AnimDone", { + params ["_caller", "_anim"]; + if (_anim isEqualTo (_caller getVariable [QGVAR(repairCurrentAnimCaller), ""])) then { + [{ + params ["_caller", "_anim"]; + if !(isNil {_caller getVariable QGVAR(repairCurrentAnimCaller)}) then { + TRACE_2("loop",_caller,_anim); + _this call EFUNC(common,doAnimation) + }; + }, [_caller, _anim], 2.5] call CBA_fnc_waitAndExecute; + }; + }]; + _caller setVariable [QGVAR(repairLoopAnimEh), _animDoneEh]; +}; + private _soundPosition = _caller modelToWorldVisualWorld (_caller selectionPosition "RightHand"); ["Acts_carFixingWheel", _soundPosition, nil, 50] call EFUNC(common,playConfigSound3D); @@ -213,7 +231,10 @@ private _hitPointClassname = if (_hitPoint isEqualType "") then { }; private _processText = getText (_config >> "displayNameProgress"); private _backupText = format [localize LSTRING(RepairingHitPoint), _hitPointClassname]; -([_hitPointClassname, _processText, _backupText] call FUNC(getHitPointString)) params ["_text"]; +private _text = _processText; +if (getNumber (_config >> "forceDisplayName") isNotEqualTo 1) then { + _text = ([_hitPointClassname, _processText, _backupText] call FUNC(getHitPointString)) select 0; +}; TRACE_4("display",_hitPoint,_hitPointClassname,_processText,_text); diff --git a/addons/repair/functions/fnc_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index 83cce85e0d..5acd9564e7 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -29,9 +29,13 @@ TRACE_5("params",_caller,_target,_selectionName,_className,_usersOfItems); if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; + +_caller removeEventHandler ["AnimDone", _caller getVariable [QGVAR(repairLoopAnimEh), -1]]; +_caller setVariable [QGVAR(repairLoopAnimEh), nil]; if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; +_caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index a86be84244..99778c37dd 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -29,9 +29,13 @@ TRACE_4("params",_caller,_target,_selectionName,_className); if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then { _caller removeWeapon "ACE_FakePrimaryWeapon"; }; + +_caller removeEventHandler ["AnimDone", _caller getVariable [QGVAR(repairLoopAnimEh), -1]]; +_caller setVariable [QGVAR(repairLoopAnimEh), nil]; if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then { [_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation); }; +_caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); diff --git a/addons/repair/initSettings.sqf b/addons/repair/initSettings.sqf index 040e44c2eb..066e944a50 100644 --- a/addons/repair/initSettings.sqf +++ b/addons/repair/initSettings.sqf @@ -107,6 +107,14 @@ private _category = format ["ACE %1", LLSTRING(Repair)]; {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; +[ + QGVAR(timeCoefficientFullRepair), "SLIDER", + [LSTRING(timeCoefficientFullRepair_name), LSTRING(timeCoefficientFullRepair_description)], + _category, + [0,3,1.5,2], + true +] call CBA_fnc_addSetting; + [ QGVAR(addSpareParts), "CHECKBOX", [LSTRING(addSpareParts_name), LSTRING(addSpareParts_description)], @@ -153,6 +161,21 @@ private _category = format ["ACE %1", LLSTRING(Repair)]; {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; +[ + QGVAR(miscRepairTime), "SLIDER", + [LSTRING(miscRepairTime_name), LSTRING(miscRepairTime_description)], + _category, + [0,60,15,-1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true +] call CBA_fnc_addSetting; + +[ + QGVAR(wheelChangeTime), "SLIDER", + [LSTRING(wheelChangeTime_name), LSTRING(wheelChangeTime_description)], + _category, + [0,60,10,-1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] + true +] call CBA_fnc_addSetting; [ QGVAR(patchWheelTime), diff --git a/addons/repair/script_component.hpp b/addons/repair/script_component.hpp index 2a6196c6fc..9fab647079 100644 --- a/addons/repair/script_component.hpp +++ b/addons/repair/script_component.hpp @@ -20,6 +20,10 @@ #define DAMAGE_COLOR_SCALE ["#FFFFFF", "#FFFF7E", "#FFEC4D", "#FFD52C", "#FCB121", "#FF9916", "#FF7D16", "#FF4400", "#FF0000"] +#define IN_REPAIR_FACILITY_CACHE_EXPIRY 1 + +#define NEAR_REPAIR_VEHICLE_CACHE_EXPIRY 1 + #define ANY_TOOLKIT_FAKECLASS QGVAR(anyToolKit) #define PATCH_WHEEL_STEP_TIME 0.05 diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 92bee905bb..4929e0f31a 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -266,6 +266,12 @@ 維修載具中... Tamir Ediliyor... + + Full Repair Time Coefficient + + + Modifies how long it takes to perform a Full Repair.\nThe repair time is based on based on the amount of repairs needed for each part, including those normally inaccessible. + Boost engineer training when in repair vehicles or facilities. Untrained becomes engineer, engineer becomes advanced engineer. Améliore les compétences en ingénierie des unités en fonction du lieu où elles se trouvent ; notamment dans les véhicules de réparation ou les ateliers.\nUn soldat non formé devient ingénieur, un ingénieur devient ingénieur avancé. @@ -1860,7 +1866,7 @@ 選擇的備件數量 - Wheel Repair Requirements + Wheel Change Requirements Bedingungen für die Reifenreperatur Wym. naprawy kół Requisitos de reparación de ruedas @@ -2062,6 +2068,18 @@ Apagar el motor automáticamente al efectuar una reparación 수리 시 엔진을 자동으로 끕니다. + + Part Repair Time + + + Time in seconds to complete a repair. + + + Wheel Change Time + + + Time in seconds to remove or change a wheel. + Patch Wheel Radflicken @@ -2071,16 +2089,16 @@ Radflicken... - Patch wheel time + Wheel Patch Time Time it takes to patch a wheel by 5%. - Patch wheel maximum repair + Patch Wheel Threshold - Maximum level a wheel can be patched. + Maximum level to which a wheel can be patched. Wheel Patch Location From 30a0e55843cf6126d1e77e0603bc7d6a87a34878 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Fri, 7 Jul 2023 07:14:35 +0300 Subject: [PATCH 5/6] Field Rations - Add arsenal category (#9221) * add field rations category * improve macro * second verse same as the first * account for empty items * switch to configClasses * documentation * add API variable * Update docs/wiki/framework/field-rations-framework.md --- addons/field_rations/CfgWeapons.hpp | 7 +++- addons/field_rations/XEH_PREP.hpp | 1 + addons/field_rations/XEH_preInit.sqf | 7 ++++ addons/field_rations/XEH_preStart.sqf | 2 ++ .../functions/fnc_scanFieldRations.sqf | 34 +++++++++++++++++++ addons/field_rations/script_component.hpp | 2 ++ .../wiki/framework/field-rations-framework.md | 1 + 7 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 addons/field_rations/functions/fnc_scanFieldRations.sqf diff --git a/addons/field_rations/CfgWeapons.hpp b/addons/field_rations/CfgWeapons.hpp index 760d41290f..b100ba4e90 100644 --- a/addons/field_rations/CfgWeapons.hpp +++ b/addons/field_rations/CfgWeapons.hpp @@ -40,6 +40,7 @@ class CfgWeapons { XGVAR(replacementItem) = "ACE_WaterBottle_Half"; XGVAR(consumeAnims)[] = {QGVAR(drinkStand), QGVAR(drinkCrouch), QGVAR(drinkProne)}; XGVAR(consumeSounds)[] = {QGVAR(drink1), QGVAR(drink1), QGVAR(drink2)}; + ACE_isFieldRationItem = 1; }; class ACE_WaterBottle_Half: ACE_WaterBottle { @@ -87,6 +88,7 @@ class CfgWeapons { XGVAR(replacementItem) = "ACE_Canteen_Half"; XGVAR(consumeAnims)[] = {QGVAR(drinkStand), QGVAR(drinkCrouch), QGVAR(drinkProne)}; XGVAR(consumeSounds)[] = {QGVAR(drink1), QGVAR(drink1), QGVAR(drink2)}; + ACE_isFieldRationItem = 1; }; class ACE_Canteen_Half: ACE_Canteen { @@ -132,6 +134,7 @@ class CfgWeapons { XGVAR(consumeText) = CSTRING(DrinkingX); XGVAR(consumeAnims)[] = {QGVAR(drinkStandCan), QGVAR(drinkCrouchCan), QGVAR(drinkProneCan)}; XGVAR(consumeSounds)[] = {QGVAR(drinkCan1), QGVAR(drinkCan1), QGVAR(drinkCan2)}; + ACE_isFieldRationItem = 1; }; class ACE_Can_Franta: ACE_Can_Spirit { @@ -164,6 +167,7 @@ class CfgWeapons { XGVAR(consumeTime) = 10; XGVAR(hungerSatiated) = 20; XGVAR(consumeText) = CSTRING(EatingX); + ACE_isFieldRationItem = 1; }; class ACE_MRE_BeefStew: ACE_MRE_LambCurry { @@ -225,7 +229,7 @@ class CfgWeapons { model = QPATHTOF(data\mre_human.p3d); picture = QPATHTOF(ui\item_mre_human_co.paa); }; - + // - Misc Food ------------------------------------------------------------ class ACE_Sunflower_Seeds: ACE_ItemCore { author = ECSTRING(common,ACETeam); @@ -240,5 +244,6 @@ class CfgWeapons { XGVAR(consumeTime) = 10; XGVAR(hungerSatiated) = 10; XGVAR(consumeText) = CSTRING(EatingX); + ACE_isFieldRationItem = 1; }; }; diff --git a/addons/field_rations/XEH_PREP.hpp b/addons/field_rations/XEH_PREP.hpp index 68833a495b..2035345f47 100644 --- a/addons/field_rations/XEH_PREP.hpp +++ b/addons/field_rations/XEH_PREP.hpp @@ -14,5 +14,6 @@ ACEX_PREP(handleEffects); ACEX_PREP(handleHUD); ACEX_PREP(handleRespawn); ACEX_PREP(refillItem); +ACEX_PREP(scanFieldRations); ACEX_PREP(setRemainingWater); ACEX_PREP(update); diff --git a/addons/field_rations/XEH_preInit.sqf b/addons/field_rations/XEH_preInit.sqf index c4efb567ed..ede921483e 100644 --- a/addons/field_rations/XEH_preInit.sqf +++ b/addons/field_rations/XEH_preInit.sqf @@ -8,6 +8,8 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" +#define ARSENAL_CATEGORY_ICON QPATHTOF(ui\icon_survival.paa) + // Init arrays of status modifiers GVAR(thirstModifiers) = []; GVAR(hungerModifiers) = []; @@ -18,4 +20,9 @@ GVAR(waterSourceP3Ds) = _cache select 0; // List of refill action offsets corresponding to the p3ds in the array above GVAR(waterSourceOffsets) = _cache select 1; +// Custom Arsenal Tab +if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [keys FIELD_RATIONS_ITEMS, LLSTRING(DisplayName), ARSENAL_CATEGORY_ICON] call EFUNC(arsenal,addRightPanelButton); +}; + ADDON = true; diff --git a/addons/field_rations/XEH_preStart.sqf b/addons/field_rations/XEH_preStart.sqf index eec59ff8f7..88109cf9ee 100644 --- a/addons/field_rations/XEH_preStart.sqf +++ b/addons/field_rations/XEH_preStart.sqf @@ -30,3 +30,5 @@ private _waterSourceOffsets = [ uiNamespace setVariable [QGVAR(cacheP3Ds), compileFinal str [_waterSourceP3Ds, _waterSourceOffsets]]; TRACE_1("compiled",count _waterSourceP3Ds); + +call FUNC(scanFieldRations); diff --git a/addons/field_rations/functions/fnc_scanFieldRations.sqf b/addons/field_rations/functions/fnc_scanFieldRations.sqf new file mode 100644 index 0000000000..395b3ba45b --- /dev/null +++ b/addons/field_rations/functions/fnc_scanFieldRations.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Salluci + * Caches all item classnames used as field rations, their thirst/hunger values, and whether they are treated as magazines + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call acex_field_rations_fnc_scanFieldRations + * + * Public: No + */ + +private _list = createHashMap; +private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgMagazines = configFile >> "CfgMagazines"; + +private _fnc_isFieldRationItem = toString { + (getNumber (_x >> "ACE_isFieldRationItem") isEqualTo 1) || {(getNumber (_x >> QXGVAR(thirstQuenched))) > 0} || {(getNumber (_x >> QXGVAR(hungerSatiated))) > 0} || {(getText (_x >> QXGVAR(refillItem))) isNotEqualTo ""} +}; + +{ + _list set [configName _x, ""]; +} forEach (_fnc_isFieldRationItem configClasses _cfgWeapons); + +{ + _list set [configName _x, ""]; +} forEach (_fnc_isFieldRationItem configClasses _cfgMagazines); + +uiNamespace setVariable [QXGVAR(fieldRationItems), compileFinal str _list]; diff --git a/addons/field_rations/script_component.hpp b/addons/field_rations/script_component.hpp index 9811493029..bcde75fe9c 100644 --- a/addons/field_rations/script_component.hpp +++ b/addons/field_rations/script_component.hpp @@ -33,3 +33,5 @@ #define IDC_DRAINING_HUD_THIRST_ICON 7750 #define IDC_DRAINING_HUD_HUNGER_GROUP 7840 #define IDC_DRAINING_HUD_HUNGER_ICON 7850 + +#define FIELD_RATIONS_ITEMS (createHashMapFromArray (call (uiNamespace getVariable [QXGVAR(fieldRationItems), {createHashMap}]))) diff --git a/docs/wiki/framework/field-rations-framework.md b/docs/wiki/framework/field-rations-framework.md index 54d2b22e90..bc433e7d52 100644 --- a/docs/wiki/framework/field-rations-framework.md +++ b/docs/wiki/framework/field-rations-framework.md @@ -28,6 +28,7 @@ Config Name | Type | Description `acex_field_rations_refillItem` | String | Makes an item refillable, class name of item added when refilled (OPTIONAL) `acex_field_rations_refillAmount` | Number | Amount of water required to refill item (OPTIONAL) `acex_field_rations_refillTime` | Number | Time required to refill item (in seconds) (OPTIONAL) +`ACE_isFieldRationItem` | Number | Force adds the item to the ACE Field Rations category in ACE Arsenal (OPTIONAL) _* Value range is 0 to 100 and can be modified by the corresponding coefficient setting._ From 0e26755b88bb5141594320cf9292fe02a05eedc7 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Fri, 7 Jul 2023 07:14:44 +0300 Subject: [PATCH 6/6] Medical - Add arsenal category (#9220) * add medical category to arsenal * function header Co-authored-by: PabstMirror * move to preinit, protect list * improve macro * documentation * add config property * add CfgMagazines * Revert "add CfgMagazines" Arsenal doesn't support magazines in custom categories --------- Co-authored-by: GhostIsSpooky <69561145+Salluci@users.noreply.github.com> Co-authored-by: PabstMirror --- addons/medical_treatment/CfgWeapons.hpp | 19 +++++++++++ addons/medical_treatment/XEH_PREP.hpp | 1 + addons/medical_treatment/XEH_preInit.sqf | 7 ++++ addons/medical_treatment/XEH_preStart.sqf | 2 ++ .../functions/fnc_scanMedicalItems.sqf | 34 +++++++++++++++++++ addons/medical_treatment/script_component.hpp | 2 ++ .../framework/medical-treatment-framework.md | 18 ++++++++++ 7 files changed, 83 insertions(+) create mode 100644 addons/medical_treatment/functions/fnc_scanMedicalItems.sqf diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index fed3184a59..e285697cc1 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -8,12 +8,14 @@ class CfgWeapons { class FirstAidKit: ItemCore { type = 0; + ACE_isMedicalItem = 1; class ItemInfo: InventoryFirstAidKitItem_Base_F { mass = 4; }; }; class Medikit: ItemCore { type = 0; + ACE_isMedicalItem = 1; class ItemInfo: MedikitItem { mass = 60; }; @@ -27,6 +29,7 @@ class CfgWeapons { displayName = CSTRING(Bandage_Basic_Display); descriptionShort = CSTRING(Bandage_Basic_Desc_Short); descriptionUse = CSTRING(Bandage_Basic_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -39,6 +42,7 @@ class CfgWeapons { model = QPATHTOF(data\packingbandage.p3d); descriptionShort = CSTRING(Packing_Bandage_Desc_Short); descriptionUse = CSTRING(Packing_Bandage_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -51,6 +55,7 @@ class CfgWeapons { model = "\A3\Structures_F_EPA\Items\Medical\Bandage_F.p3d"; descriptionShort = CSTRING(Bandage_Elastic_Desc_Short); descriptionUse = CSTRING(Bandage_Elastic_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -63,6 +68,7 @@ class CfgWeapons { model = QPATHTOF(data\tourniquet.p3d); descriptionShort = CSTRING(Tourniquet_Desc_Short); descriptionUse = CSTRING(Tourniquet_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -74,6 +80,7 @@ class CfgWeapons { picture = QPATHTOF(ui\splint_ca.paa); model = QPATHTOF(data\splint.p3d); descriptionShort = CSTRING(splint_Desc_Short); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 2; }; @@ -86,6 +93,7 @@ class CfgWeapons { model = QPATHTOF(data\morphine.p3d); descriptionShort = CSTRING(Morphine_Desc_Short); descriptionUse = CSTRING(Morphine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -98,6 +106,7 @@ class CfgWeapons { model = QPATHTOF(data\adenosine.p3d); descriptionShort = CSTRING(adenosine_Desc_Short); descriptionUse = CSTRING(adenosine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -110,6 +119,7 @@ class CfgWeapons { model = QPATHTOF(data\atropine.p3d); descriptionShort = CSTRING(Atropine_Desc_Short); descriptionUse = CSTRING(Atropine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -122,6 +132,7 @@ class CfgWeapons { model = QPATHTOF(data\epinephrine.p3d); descriptionShort = CSTRING(Epinephrine_Desc_Short); descriptionUse = CSTRING(Epinephrine_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -137,6 +148,7 @@ class CfgWeapons { picture = QPATHTOF(ui\plasmaIV_ca.paa); descriptionShort = CSTRING(Plasma_IV_Desc_Short); descriptionUse = CSTRING(Plasma_IV_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -167,6 +179,7 @@ class CfgWeapons { hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_1000ml_ca.paa)}; descriptionShort = CSTRING(Blood_IV_Desc_Short); descriptionUse = CSTRING(Blood_IV_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -197,6 +210,7 @@ class CfgWeapons { picture = QPATHTOF(ui\salineIV_ca.paa); descriptionShort = CSTRING(Saline_IV_Desc_Short); descriptionUse = CSTRING(Saline_IV_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -225,6 +239,7 @@ class CfgWeapons { picture = QPATHTOF(ui\quickclot_ca.paa); descriptionShort = CSTRING(QuikClot_Desc_Short); descriptionUse = CSTRING(QuikClot_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -236,6 +251,7 @@ class CfgWeapons { picture = QPATHTOF(ui\personal_aid_kit_ca.paa); descriptionShort = CSTRING(Aid_Kit_Desc_Short); descriptionUse = CSTRING(Aid_Kit_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 10; }; @@ -248,6 +264,7 @@ class CfgWeapons { picture = QPATHTOF(ui\surgicalKit_ca.paa); descriptionShort = CSTRING(SurgicalKit_Desc_Short); descriptionUse = CSTRING(SurgicalKit_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 15; }; @@ -260,6 +277,7 @@ class CfgWeapons { picture = QPATHTOF(ui\suture_ca.paa); descriptionShort = CSTRING(Suture_Desc_Short); descriptionUse = CSTRING(Suture_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 1; }; @@ -272,6 +290,7 @@ class CfgWeapons { picture = QPATHTOF(ui\bodybag_ca.paa); descriptionShort = CSTRING(Bodybag_Desc_Short); descriptionUse = CSTRING(Bodybag_Desc_Use); + ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { mass = 7; }; diff --git a/addons/medical_treatment/XEH_PREP.hpp b/addons/medical_treatment/XEH_PREP.hpp index be64563857..ab128aa49c 100644 --- a/addons/medical_treatment/XEH_PREP.hpp +++ b/addons/medical_treatment/XEH_PREP.hpp @@ -48,6 +48,7 @@ PREP(medicationLocal); PREP(onMedicationUsage); PREP(placeInBodyBag); PREP(removeBody); +PREP(scanMedicalItems); PREP(setTriageStatus); PREP(splint); PREP(splintLocal); diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index dfb6bf6518..30bf875291 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -8,6 +8,8 @@ PREP_RECOMPILE_END; #include "initSettings.sqf" +#define ARSENAL_CATEGORY_ICON (["\A3\ui_f\data\igui\cfg\actions\heal_ca.paa", QPATHTOEF(medical_gui,data\categories\bandage_fracture.paa)] select (["ace_medical_gui"] call EFUNC(common,isModLoaded))) + // config to determine animation acceleration coefficient // adjusting these is trail and error // if the animation is cut of ingame, increase these values @@ -44,4 +46,9 @@ GVAR(facilityClasses) = []; } forEach getArray _x; } forEach configProperties [configFile >> QEGVAR(medical,facilities), "isArray _x"]; +// Custom Arsenal tab +if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [MEDICAL_TREATMENT_ITEMS, LELSTRING(medical,Category), ARSENAL_CATEGORY_ICON] call EFUNC(arsenal,addRightPanelButton); +}; + ADDON = true; diff --git a/addons/medical_treatment/XEH_preStart.sqf b/addons/medical_treatment/XEH_preStart.sqf index 022888575e..27f8f2d9c2 100644 --- a/addons/medical_treatment/XEH_preStart.sqf +++ b/addons/medical_treatment/XEH_preStart.sqf @@ -1,3 +1,5 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +call FUNC(scanMedicalItems) diff --git a/addons/medical_treatment/functions/fnc_scanMedicalItems.sqf b/addons/medical_treatment/functions/fnc_scanMedicalItems.sqf new file mode 100644 index 0000000000..17b2456c42 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_scanMedicalItems.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Salluci + * Caches all item classnames used in ACE_Medical_Treatment_Actions + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_medical_treatment_fnc_scanMedicalItems + * + * Public: No + */ + +private _list = []; +private _cfgActions = configFile >> QGVAR(actions); + +private _fnc_isMedicalItem = toString { + getNumber (_x >> "ACE_isMedicalItem") isEqualTo 1 +}; + +// get items in ACE_Medical_Treament_Actions, fallback for items without API config property +{ + _list append (getArray (_x >> "items")); +} forEach ("true" configClasses _cfgActions); + +{ + _list pushBack (configName _x); +} forEach (_fnc_isMedicalItem configClasses (configFile >> "CfgWeapons")); + +uiNamespace setVariable [QGVAR(treatmentItems), compileFinal str (_list arrayIntersect _list)] diff --git a/addons/medical_treatment/script_component.hpp b/addons/medical_treatment/script_component.hpp index 682e8a471c..36173d4ac1 100644 --- a/addons/medical_treatment/script_component.hpp +++ b/addons/medical_treatment/script_component.hpp @@ -54,3 +54,5 @@ // Animations that would be played faster than this are instead skipped. (= Progress bar too quick for animation). #define ANIMATION_SPEED_MAX_COEFFICIENT 2.5 + +#define MEDICAL_TREATMENT_ITEMS (call (uiNamespace getVariable [QGVAR(treatmentItems), {[]}])) diff --git a/docs/wiki/framework/medical-treatment-framework.md b/docs/wiki/framework/medical-treatment-framework.md index a3f5d04de1..adb9cd485d 100644 --- a/docs/wiki/framework/medical-treatment-framework.md +++ b/docs/wiki/framework/medical-treatment-framework.md @@ -38,3 +38,21 @@ class CfgVehicles { }; }; ``` +### 1.3 Treatment Items + +Items in `CfgWeapons` with `ACE_isMedicalItem` property will be added to the ACE Medical category in the ACE Arsenal. +```cpp +class CfgWeapons { + class MyMedicalItem { + ACE_isMedicalItem = 1; + }; +}; +``` +Required items in `ACE_Medical_Treatment_Actions` will also be added as a fallback. +```cpp +class ACE_Medical_Treatment_Actions { + class MyCustomTreatment { + items[] = {"MyMedicalItem"}; + }; +}; +```