diff --git a/addons/medical_damage/functions/fnc_determineIfFatal.sqf b/addons/medical_damage/functions/fnc_determineIfFatal.sqf index 1e5c533e98b..c56763ef479 100644 --- a/addons/medical_damage/functions/fnc_determineIfFatal.sqf +++ b/addons/medical_damage/functions/fnc_determineIfFatal.sqf @@ -6,7 +6,7 @@ * Arguments: * 0: The Unit * 1: Part No - * 2: Damage Array - QGVAR(medical,bodyPartDamage) + * 2: Damage Array - QEGVAR(medical,bodyPartDamage) * 3: New Damage * * ReturnValue: @@ -20,7 +20,7 @@ params ["_unit", "_part", "_bodyPartDamage", "_woundDamage"]; -if (_part > 1) exitWith { false }; +if (_part > 1 && EGVAR(medical,useLimbDamage) == 0) exitWith { false }; scopeName "main"; @@ -46,6 +46,15 @@ if (EGVAR(medical,fatalDamageSource) in [1, 2]) then { _bodyPartDamage params ["_headDamage", "_bodyDamage"]; private _vitalDamage = ((_headDamage - _headThreshhold) max 0) + ((_bodyDamage - _bodyThreshhold) max 0); + + // Sum of trauma to the limbs can also be fatal (shock) but this should take much more damage at default (5x as much) + if ([false, !isPlayer _unit, true] select EGVAR(medical,useLimbDamage)) then { + private _limbThreshold = EGVAR(medical,limbDamageThreshold) * _damageThreshold; + { + _vitalDamage = _vitalDamage + ((_x - _limbThreshold) max 0); + } forEach _bodyPartDamage select [2]; + }; + private _chanceFatal = 1 - exp -((_vitalDamage/FATAL_SUM_DAMAGE_WEIBULL_L)^FATAL_SUM_DAMAGE_WEIBULL_K); TRACE_3("",_bodyPartDamage,_vitalDamage,_chanceFatal); @@ -56,4 +65,3 @@ if (EGVAR(medical,fatalDamageSource) in [1, 2]) then { }; false - diff --git a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf index b352564b45d..391d69c08bf 100644 --- a/addons/medical_damage/functions/fnc_handleIncapacitation.sqf +++ b/addons/medical_damage/functions/fnc_handleIncapacitation.sqf @@ -20,7 +20,7 @@ params ["_unit"]; private _painLevel = GET_PAIN_PERCEIVED(_unit); private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; -_bodyPartDamage params ["_headDamage", "_bodyDamage", "_leftArmDamage", "_rightArmDamage", "_leftLegDamage", "_rightLegDamage"]; +_bodyPartDamage params ["_headDamage", "_bodyDamage"]; // Exclude non penetrating body damage { diff --git a/addons/medical_damage/initSettings.inc.sqf b/addons/medical_damage/initSettings.inc.sqf index 229b086505c..c6d7f49e343 100644 --- a/addons/medical_damage/initSettings.inc.sqf +++ b/addons/medical_damage/initSettings.inc.sqf @@ -2,7 +2,7 @@ QEGVAR(medical,fatalDamageSource), "LIST", [LSTRING(fatalDamageSource_DisplayName), LSTRING(fatalDamageSource_Description)], - [ELSTRING(medical,Category)], + ELSTRING(medical,Category), [[0, 1, 2], [LSTRING(fatalDamageSource_vitalShotsOnly), LSTRING(fatalDamageSource_trauma), LSTRING(fatalDamageSource_both)], 2], true ] call CBA_fnc_addSetting; @@ -25,6 +25,24 @@ true ] call CBA_fnc_addSetting; +[ + QEGVAR(medical,useLimbDamage), + "LIST", + [LSTRING(useLimbDamage_DisplayName), LSTRING(useLimbDamage_Description)], + ELSTRING(medical,Category), + [[0, 1, 2], [ELSTRING(common,Never), ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)], 0], + 1 +] call CBA_fnc_addSetting; + +[ + QEGVAR(medical,limbDamageThreshold), + "SLIDER", + [LSTRING(limbDamageThreshold_DisplayName), LSTRING(limbDamageThreshold_Description)], + ELSTRING(medical,Category), + [0, 25, 5, 2], + 1 +] call CBA_fnc_addSetting; + [ QEGVAR(medical,painUnconsciousChance), "SLIDER", diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index fa4e1c4ae48..f8f7e22e895 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -843,5 +843,21 @@ 치명상으로 인해 사망할 확률을 정합니다. A chance de morrer para um ferimento fatal. + + Use Limb Damage + Использовать урон конечностям + + + Controls whether limb damage is taken into account for sum of trauma calculations. + Определяет, учитывается ли повреждение конечностей при расчете совокупности травм. + + + Limb Damage Threshold + Порог повреждения конечностей + + + Sets the amount of damage limbs can receive before going critical, leading to death. Must be over 0 for any effect.\nRequires the "Use Limb Damage" setting to be enabled and "Fatal Damage Source" to be set to "Sum of Trauma" or "Either".\nStacks multiplicatively with the overall unit Damage Threshold. Doesn't interact with fractures/limping at all. + Устанавливает величину урона, который могут получить конечности, прежде чем урон станет критическим, что приведет к смерти. Для любого эффекта должно быть больше 0.\nТребуется, чтобы настройка "Использовать урон конечностям" была включена, а "Причина смертельного урона" была установлена на "Совокупность травмы" или "Оба".\nУмножается с общим порогом повреждения. Никак не взаимодействует с переломами или хроманием. + diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index b8ee8ee240e..71b86449280 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -77,12 +77,22 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; [_bloodLoss] call FUNC(bloodLossToRGBA); } else { private _damage = _bodyPartDamage select _forEachIndex; + // _damageThreshold here indicates how close unit is to guaranteed death via sum of trauma, so use the same multipliers used in medical_damage/functions/fnc_determineIfFatal.sqf + // TODO: make multipliers for head and torso a macro in medical_engine/script_macros_medical.hpp switch (true) do { // torso damage threshold doesn't need scaling case (_forEachIndex > 3): { // legs: index 4 & 5 - _damageThreshold = LIMPING_DAMAGE_THRESHOLD * 4; + if (!EGVAR(medical,useLimbDamage) || EGVAR(medical,limbDamageThreshold) == 0) then { // Just indicate how close to the limping threshold we are + _damageThreshold = LIMPING_DAMAGE_THRESHOLD * 4; + } else { + _damageThreshold = _damageThreshold * EGVAR(medical,limbDamageThreshold); + }; }; case (_forEachIndex > 1): { // arms: index 2 & 3 - _damageThreshold = FRACTURE_DAMAGE_THRESHOLD * 4; + if (!EGVAR(medical,useLimbDamage) || EGVAR(medical,limbDamageThreshold) == 0) then { // Just indicate how close to the fracture threshold we are + _damageThreshold = FRACTURE_DAMAGE_THRESHOLD * 4; + } else { + _damageThreshold = _damageThreshold * EGVAR(medical,limbDamageThreshold); + }; }; case (_forEachIndex == 0): { // head: index 0 _damageThreshold = _damageThreshold * 1.25; diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 3219eb025f5..f7a9eec1122 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -168,10 +168,18 @@ if (GVAR(showDamageEntry)) then { private _damageThreshold = GET_DAMAGE_THRESHOLD(_target); switch (true) do { case (_selectionN > 3): { // legs: index 4 & 5 - _damageThreshold = LIMPING_DAMAGE_THRESHOLD * 4; + if (!EGVAR(medical,useLimbDamage) || EGVAR(medical,limbDamageThreshold) == 0) then { // Just indicate how close to the limping threshold we are + _damageThreshold = LIMPING_DAMAGE_THRESHOLD * 4; + } else { + _damageThreshold = _damageThreshold * EGVAR(medical,limbDamageThreshold); + }; }; case (_selectionN > 1): { // arms: index 2 & 3 - _damageThreshold = FRACTURE_DAMAGE_THRESHOLD * 4; + if (!EGVAR(medical,useLimbDamage) || EGVAR(medical,limbDamageThreshold) == 0) then { // Just indicate how close to the fracture threshold we are + _damageThreshold = FRACTURE_DAMAGE_THRESHOLD * 4; + } else { + _damageThreshold = _damageThreshold * EGVAR(medical,limbDamageThreshold); + }; }; case (_selectionN == 0): { // head: index 0 _damageThreshold = _damageThreshold * 1.25; @@ -180,6 +188,7 @@ if (GVAR(showDamageEntry)) then { _damageThreshold = _damageThreshold * 1.5; }; }; + // _bodyPartDamage here should indicate how close unit is to guaranteed death via sum of trauma, so use the same multipliers used in medical_damage/functions/fnc_determineIfFatal.sqf _bodyPartDamage = (_bodyPartDamage / _damageThreshold) min 1; switch (true) do { case (_bodyPartDamage isEqualTo 1): {