Medical - Death from sum of trauma (#7195)

* Medical - Death from sum of trauma

* fixes

* Update fnc_determineIfFatal.sqf
This commit is contained in:
PabstMirror 2019-10-08 10:45:09 -05:00 committed by GitHub
parent a71879ccea
commit 4eeac9f649
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 143 additions and 16 deletions

View File

@ -61,7 +61,7 @@ GVAR(dev_watchVariableRunning) = true;
// Damage: // Damage:
private _damage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; private _damage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _limping = if (_unit getVariable [QEGVAR(medical,isLimping), false]) then {"[<t color ='#FFCC22'> Limping </t>]"} else {""}; private _limping = if (_unit getVariable [QEGVAR(medical,isLimping), false]) then {"[<t color ='#FFCC22'> Limping </t>]"} else {""};
_return pushBack format ["Damage: [H: %1] [B: %2] %3", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2]; _return pushBack format ["BodyPartDamage: [H: %1] [B: %2]", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2];
_return pushBack format ["[LA:%1] [RA: %2] [LL:%3] [RL: %4]", (_damage select 2) toFixed 2, (_damage select 3) toFixed 2, (_damage select 4) toFixed 2, (_damage select 5) toFixed 2]; _return pushBack format ["[LA:%1] [RA: %2] [LL:%3] [RL: %4]", (_damage select 2) toFixed 2, (_damage select 3) toFixed 2, (_damage select 4) toFixed 2, (_damage select 5) toFixed 2];
_return pushBack format ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2]; _return pushBack format ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2];

View File

@ -1,3 +1,4 @@
PREP(determineIfFatal);
PREP(getTypeOfDamage); PREP(getTypeOfDamage);
PREP(handleIncapacitation); PREP(handleIncapacitation);
PREP(parseConfigForInjuries); PREP(parseConfigForInjuries);

View File

@ -0,0 +1,62 @@
#include "script_component.hpp"
/*
* Author: PabstMirror, Glowbal
* Determines if damage is fatal
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Part No <NUMBER>
* 2: Damage Array - QGVAR(medical,bodyPartDamage) <ARRAY>
* 3: New Damage <NUMBER>
*
* ReturnValue:
* Was Fatal <BOOL>
*
* Example:
* [player, 0, 1.4, 0.7] call ace_medical_damage_fnc_determineIfFatal
*
* Public: No
*/
#define WEIBULL_K 6.5625
#define WEIBULL_L 0.704523
params ["_unit", "_part", "_bodyPartDamage", "_woundDamage"];
if (_part > 1) exitWith { false };
scopeName "main";
if (EGVAR(medical,fatalDamageSource) in [0, 2]) then {
// Emulate damage to vital organs - Original rewrite logic, only powerfull headshots or random torso shots
if (_part == 0 && {_woundDamage >= HEAD_DAMAGE_THRESHOLD}) exitWith {
// Fatal damage to the head is guaranteed death
TRACE_1("determineIfFatal: lethal headshot",_woundDamage);
true breakOut "main";
};
if (_part == 1 && {_woundDamage >= ORGAN_DAMAGE_THRESHOLD} && {random 1 < HEART_HIT_CHANCE}) exitWith {
// Fatal damage to torso has various results based on organ hit - Heart shot is lethal
TRACE_1("determineIfFatal: lethal heartshot",_woundDamage);
true breakOut "main";
};
};
if (EGVAR(medical,fatalDamageSource) in [1, 2]) then {
// Sum of trauma to critical areas can be fatal (e.g. many small hits)
private _damageThreshold = if (isPlayer _unit) then { EGVAR(medical,playerDamageThreshold) } else { EGVAR(medical,AIDamageThreshold) };
private _headThreshhold = 1.25 * _damageThreshold;
private _bodyThreshhold = 1.5 * _damageThreshold;
_bodyPartDamage params ["_headDamage", "_bodyDamage"];
private _vitalDamage = ((_headDamage - _headThreshhold) max 0) + ((_bodyDamage - _bodyThreshhold) max 0);
private _chanceFatal = 1 - exp -((_vitalDamage/WEIBULL_L)^WEIBULL_K);
TRACE_3("",_bodyPartDamage,_vitalDamage,_chanceFatal);
if (_chanceFatal > random 1) exitWith {
TRACE_1("determineIfFatal: lethal trauma",_woundDamage);
true breakOut "main";
};
};
false

View File

@ -121,26 +121,16 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra
if (_bodyPartNToAdd == 0 || {_bodyPartNToAdd == 1 && {_woundDamage > PENETRATION_THRESHOLD}}) then { if (_bodyPartNToAdd == 0 || {_bodyPartNToAdd == 1 && {_woundDamage > PENETRATION_THRESHOLD}}) then {
_critialDamage = true; _critialDamage = true;
}; };
if ([_unit, _bodyPartNToAdd, _bodyPartDamage, _woundDamage] call FUNC(determineIfFatal)) then {
TRACE_1("determineIfFatal returned true",_woundDamage);
[QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent;
};
#ifdef DEBUG_MODE_FULL #ifdef DEBUG_MODE_FULL
systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, _woundDamage toFixed 2, _woundDamage > PENETRATION_THRESHOLD, _bleeding toFixed 3, _pain toFixed 3]; systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, _woundDamage toFixed 2, _woundDamage > PENETRATION_THRESHOLD, _bleeding toFixed 3, _pain toFixed 3];
#endif #endif
// Emulate damage to vital organs
switch (true) do { switch (true) do {
// Fatal damage to the head is guaranteed death
case (_bodyPartNToAdd == 0 && {_woundDamage >= HEAD_DAMAGE_THRESHOLD}): {
TRACE_1("lethal headshot",_woundDamage toFixed 2);
[QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent;
};
// Fatal damage to torso has various results based on organ hit
case (_bodyPartNToAdd == 1 && {_woundDamage >= ORGAN_DAMAGE_THRESHOLD}): {
// Heart shot is lethal
if (random 1 < HEART_HIT_CHANCE) then {
TRACE_1("lethal heartshot",_woundDamage toFixed 2);
[QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent;
};
};
case (_causeFracture && {EGVAR(medical,fractures) > 0} && {_bodyPartNToAdd > 1} && {_woundDamage > FRACTURE_DAMAGE_THRESHOLD}): { case (_causeFracture && {EGVAR(medical,fractures) > 0} && {_bodyPartNToAdd > 1} && {_woundDamage > FRACTURE_DAMAGE_THRESHOLD}): {
TRACE_1("limb fracture",_bodyPartNToAdd); TRACE_1("limb fracture",_bodyPartNToAdd);
private _fractures = GET_FRACTURES(_unit); private _fractures = GET_FRACTURES(_unit);

View File

@ -1,3 +1,12 @@
[
QEGVAR(medical,fatalDamageSource),
"LIST",
[LSTRING(fatalDamageSource_DisplayName), LSTRING(fatalDamageSource_Description)],
[ELSTRING(medical,Category)],
[[0, 1, 2], [LSTRING(fatalDamageSource_vitalShotsOnly), LSTRING(fatalDamageSource_trauma), LSTRING(fatalDamageSource_both)], 0],
true
] call CBA_settings_fnc_init;
[ [
QEGVAR(medical,playerDamageThreshold), QEGVAR(medical,playerDamageThreshold),
"SLIDER", "SLIDER",

View File

@ -4,7 +4,7 @@
// #define DEBUG_MODE_FULL // #define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE // #define DISABLE_COMPILE_CACHE
//#define ENABLE_PERFORMANCE_COUNTERS // #define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_MEDICAL_DAMAGE #ifdef DEBUG_ENABLED_MEDICAL_DAMAGE
#define DEBUG_MODE_FULL #define DEBUG_MODE_FULL

View File

@ -477,5 +477,20 @@
<Japanese>大きな刺し傷</Japanese> <Japanese>大きな刺し傷</Japanese>
<Korean>대형 관통상</Korean> <Korean>대형 관통상</Korean>
</Key> </Key>
<Key ID="STR_ACE_Medical_Damage_fatalDamageSource_DisplayName">
<English>Fatal Damage Source</English>
</Key>
<Key ID="STR_ACE_Medical_Damage_fatalDamageSource_Description">
<English>Determines what damage can be fatal</English>
</Key>
<Key ID="STR_ACE_Medical_Damage_fatalDamageSource_vitalShotsOnly">
<English>Only large hits to vital organs</English>
</Key>
<Key ID="STR_ACE_Medical_Damage_fatalDamageSource_trauma">
<English>Sum of trauma</English>
</Key>
<Key ID="STR_ACE_Medical_Damage_fatalDamageSource_both">
<English>Either</English>
</Key>
</Package> </Package>
</Project> </Project>

View File

@ -18,6 +18,7 @@
*/ */
params ["_patient", "_bodyPart", "_bandage"]; params ["_patient", "_bodyPart", "_bandage"];
TRACE_3("bandageLocal",_patient,_bodyPart,_bandage);
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
if (_partIndex < 0) exitWith {false}; if (_partIndex < 0) exitWith {false};
@ -54,4 +55,26 @@ if ((EGVAR(medical,limping) == 1) && {_partIndex > 3} && {_amountOf <= 0} && {_p
[_patient] call EFUNC(medical_engine,updateDamageEffects); [_patient] call EFUNC(medical_engine,updateDamageEffects);
}; };
if (GVAR(clearTraumaAfterBandage)) then {
TRACE_2("clearTraumaAfterBandage - checking open wounds",_partIndex,_openWounds);
if ((_openWounds findIf {
_x params ["", "_xBodyPartN", "_xAmountOf"];
(_partIndex ==_xBodyPartN) && {_xAmountOf > 0}
}) == -1) then {
private _bodyPartDamage = _patient getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
_bodyPartDamage set [_partIndex, 0];
_patient setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
TRACE_2("fully healed",_partIndex,_bodyPartDamage);
switch (_partIndex) do {
case 0: { [_patient, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case 1: { [_patient, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case 2;
case 3: { [_patient, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
default { [_patient, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); };
};
};
};
true true

View File

@ -29,6 +29,15 @@
true true
] call CBA_settings_fnc_init; ] call CBA_settings_fnc_init;
[
QGVAR(clearTraumaAfterBandage),
"CHECKBOX",
[LSTRING(clearTraumaAfterBandage_DisplayName), LSTRING(clearTraumaAfterBandage_Description)],
[ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)],
false,
true
] call CBA_settings_fnc_init;
[ [
QGVAR(advancedMedication), QGVAR(advancedMedication),
"CHECKBOX", "CHECKBOX",

View File

@ -3687,5 +3687,23 @@
<Chinesesimp>个人急救包使用条件</Chinesesimp> <Chinesesimp>个人急救包使用条件</Chinesesimp>
<Chinese>個人急救包使用條件</Chinese> <Chinese>個人急救包使用條件</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Medical_Treatment_clearTraumaAfterBandage_DisplayName">
<English>Clear Trauma After Bandage</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_clearTraumaAfterBandage_Description">
<English>Heal fully bandaged hitpoints</English>
<Polish>Lecz w pełni zabandażowane hitpointy</Polish>
<Spanish>Curar miembros totalmente vendados</Spanish>
<Russian>Исцелять полностью перебинтованные части тела</Russian>
<Portuguese>Curar pontos de vida totalmente enfaixados</Portuguese>
<Czech>Heal fully bandaged hitpoints</Czech>
<Italian>Cura hitpoints completamente bendati</Italian>
<French>Soigner les plaies entièrement bandées</French>
<German>Heilt vollständig bandagierte Trefferpunkte</German>
<Japanese>包帯は体力を完全に回復する</Japanese>
<Korean>붕대를 감은후 체력을 회복함</Korean>
<Chinesesimp>完全医疗包扎的部位至痊愈</Chinesesimp>
<Chinese>完全醫療包紮的部位至痊癒</Chinese>
</Key>
</Package> </Package>
</Project> </Project>