mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Medical - Death from sum of trauma (#7195)
* Medical - Death from sum of trauma * fixes * Update fnc_determineIfFatal.sqf
This commit is contained in:
parent
a71879ccea
commit
4eeac9f649
@ -61,7 +61,7 @@ GVAR(dev_watchVariableRunning) = true;
|
||||
// Damage:
|
||||
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 {""};
|
||||
_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 ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2];
|
||||
|
@ -1,3 +1,4 @@
|
||||
PREP(determineIfFatal);
|
||||
PREP(getTypeOfDamage);
|
||||
PREP(handleIncapacitation);
|
||||
PREP(parseConfigForInjuries);
|
||||
|
62
addons/medical_damage/functions/fnc_determineIfFatal.sqf
Normal file
62
addons/medical_damage/functions/fnc_determineIfFatal.sqf
Normal 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
|
||||
|
@ -121,26 +121,16 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra
|
||||
if (_bodyPartNToAdd == 0 || {_bodyPartNToAdd == 1 && {_woundDamage > PENETRATION_THRESHOLD}}) then {
|
||||
_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
|
||||
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
|
||||
|
||||
// Emulate damage to vital organs
|
||||
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}): {
|
||||
TRACE_1("limb fracture",_bodyPartNToAdd);
|
||||
private _fractures = GET_FRACTURES(_unit);
|
||||
|
@ -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),
|
||||
"SLIDER",
|
||||
|
@ -477,5 +477,20 @@
|
||||
<Japanese>大きな刺し傷</Japanese>
|
||||
<Korean>대형 관통상</Korean>
|
||||
</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>
|
||||
</Project>
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
params ["_patient", "_bodyPart", "_bandage"];
|
||||
TRACE_3("bandageLocal",_patient,_bodyPart,_bandage);
|
||||
|
||||
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
|
||||
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);
|
||||
};
|
||||
|
||||
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
|
||||
|
@ -29,6 +29,15 @@
|
||||
true
|
||||
] 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),
|
||||
"CHECKBOX",
|
||||
|
@ -3687,5 +3687,23 @@
|
||||
<Chinesesimp>个人急救包使用条件</Chinesesimp>
|
||||
<Chinese>個人急救包使用條件</Chinese>
|
||||
</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>
|
||||
</Project>
|
||||
|
Loading…
Reference in New Issue
Block a user