mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Medical - Fix severity of wound bleeding and adjust cardiac output calculations (#7010)
* Fix severity of wound bleeding I'm simplifying the nastiness calculations so that the wound config specifies the worst wound and we scale it between 25% to 100% based on the wound damage and number of wounds recieved. Similarly I've updated the wound configs to more reasonable maximum bleeding values based on the fact that they're percentages of cardiac output being bled. * Limit variance of pain modifier This is to avoid unexpectedly high pain for small wounds or unexpectedly small pain for large wounds * Make more wounds increase chance for nastiness Rather than guarantee * Adjust worst damage scaling This handles torso wounds better as they're typically around 0.3-0.6 for 6.5mm shots which makes them roughly medium sized. * Fix cardiac output calculation Previously the calculation didn't make sense as it wasn't outputting a value in l/s. This method of calculation makes more logical sense and provides a point of reference for what the bleeding values actually represent (percentage of the blood being pumped that is lost - which now has an actual volumetric value). * Fix blood pressure after change to cardiac output * Fix heartrate skyrocketing between 5l and 4l blood Pretty sure someone accidnentally got these conditions the wrong way around. This way blood pressure will first drop and then heart rate will later go up to compensate. * Fix comment typo Co-Authored-By: PabstMirror <pabstmirror@gmail.com>
This commit is contained in:
parent
aff2cea0fb
commit
8483a4bcdc
@ -1,4 +1,4 @@
|
|||||||
// bleeding - maximum possible bleeding rate for a given wound type (0 .. 1)
|
// bleeding - maximum possible percentage of cardiac output bled for a given wound type (0 .. 1)
|
||||||
// pain - maximum possible pain level for a given wound type (0 .. 1)
|
// pain - maximum possible pain level for a given wound type (0 .. 1)
|
||||||
|
|
||||||
class ACE_Medical_Injuries {
|
class ACE_Medical_Injuries {
|
||||||
@ -16,7 +16,7 @@ class ACE_Medical_Injuries {
|
|||||||
// Occur when an entire structure or part of it is forcibly pulled away, such as the loss of a permanent tooth or an ear lobe. Explosions, gunshots, and animal bites may cause avulsions.
|
// Occur when an entire structure or part of it is forcibly pulled away, such as the loss of a permanent tooth or an ear lobe. Explosions, gunshots, and animal bites may cause avulsions.
|
||||||
class Avulsion {
|
class Avulsion {
|
||||||
causes[] = {"explosive", "vehiclecrash", "collision", "grenade", "shell", "bullet", "backblast", "bite"};
|
causes[] = {"explosive", "vehiclecrash", "collision", "grenade", "shell", "bullet", "backblast", "bite"};
|
||||||
bleeding = 0.25;
|
bleeding = 0.1;
|
||||||
pain = 1.0;
|
pain = 1.0;
|
||||||
minDamage = 0.01;
|
minDamage = 0.01;
|
||||||
causeLimping = 1;
|
causeLimping = 1;
|
||||||
@ -24,7 +24,7 @@ class ACE_Medical_Injuries {
|
|||||||
// Also called bruises, these are the result of a forceful trauma that injures an internal structure without breaking the skin. Blows to the chest, abdomen, or head with a blunt instrument (e.g. a football or a fist) can cause contusions.
|
// Also called bruises, these are the result of a forceful trauma that injures an internal structure without breaking the skin. Blows to the chest, abdomen, or head with a blunt instrument (e.g. a football or a fist) can cause contusions.
|
||||||
class Contusion {
|
class Contusion {
|
||||||
causes[] = {"bullet", "backblast", "punch", "vehiclecrash", "collision", "falling"};
|
causes[] = {"bullet", "backblast", "punch", "vehiclecrash", "collision", "falling"};
|
||||||
bleeding = 0.0;
|
bleeding = 0;
|
||||||
pain = 0.3;
|
pain = 0.3;
|
||||||
minDamage = 0.02;
|
minDamage = 0.02;
|
||||||
maxDamage = 0.35;
|
maxDamage = 0.35;
|
||||||
@ -41,7 +41,7 @@ class ACE_Medical_Injuries {
|
|||||||
// Slicing wounds made with a sharp instrument, leaving even edges. They may be as minimal as a paper cut or as significant as a surgical incision.
|
// Slicing wounds made with a sharp instrument, leaving even edges. They may be as minimal as a paper cut or as significant as a surgical incision.
|
||||||
class Cut {
|
class Cut {
|
||||||
causes[] = {"vehiclecrash", "collision", "grenade", "explosive", "shell", "backblast", "stab", "unknown"};
|
causes[] = {"vehiclecrash", "collision", "grenade", "explosive", "shell", "backblast", "stab", "unknown"};
|
||||||
bleeding = 0.04;
|
bleeding = 0.01;
|
||||||
pain = 0.1;
|
pain = 0.1;
|
||||||
minDamage = 0.1;
|
minDamage = 0.1;
|
||||||
};
|
};
|
||||||
@ -56,7 +56,7 @@ class ACE_Medical_Injuries {
|
|||||||
// Also called velocity wounds, they are caused by an object entering the body at a high speed, typically a bullet or small peices of shrapnel.
|
// Also called velocity wounds, they are caused by an object entering the body at a high speed, typically a bullet or small peices of shrapnel.
|
||||||
class VelocityWound {
|
class VelocityWound {
|
||||||
causes[] = {"bullet", "grenade","explosive", "shell", "unknown"};
|
causes[] = {"bullet", "grenade","explosive", "shell", "unknown"};
|
||||||
bleeding = 0.5;
|
bleeding = 0.2;
|
||||||
pain = 0.9;
|
pain = 0.9;
|
||||||
minDamage = 0.35;
|
minDamage = 0.35;
|
||||||
causeLimping = 1;
|
causeLimping = 1;
|
||||||
|
@ -75,11 +75,11 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra
|
|||||||
|
|
||||||
{
|
{
|
||||||
_x params ["_thresholdMinDam", "_thresholdWoundCount"];
|
_x params ["_thresholdMinDam", "_thresholdWoundCount"];
|
||||||
if (_thresholdMinDam <= _damage) exitWith {
|
if (_damage > _thresholdMinDam) exitWith {
|
||||||
private _woundDamage = _damage / (_thresholdWoundCount max 1); // If the damage creates multiple wounds
|
private _woundDamage = _damage / (_thresholdWoundCount max 1); // If the damage creates multiple wounds
|
||||||
for "_i" from 1 to _thresholdWoundCount do {
|
for "_i" from 1 to _thresholdWoundCount do {
|
||||||
// Find the injury we are going to add. Format [ classID, allowdSelections, bleedingRate, injuryPain]
|
// Find the injury we are going to add. Format [ classID, allowedSelections, bleedingRate, injuryPain]
|
||||||
private _oldInjury = if (random 1 >= 0.85) then {
|
private _oldInjury = if (random 1 < 0.15) then {
|
||||||
_woundTypes select _highestPossibleSpot
|
_woundTypes select _highestPossibleSpot
|
||||||
} else {
|
} else {
|
||||||
selectRandom _allPossibleInjuries
|
selectRandom _allPossibleInjuries
|
||||||
@ -93,17 +93,24 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra
|
|||||||
_bodyPartVisParams set [[1,2,3,3,4,4] select _bodyPartNToAdd, true]; // Mark the body part index needs updating
|
_bodyPartVisParams set [[1,2,3,3,4,4] select _bodyPartNToAdd, true]; // Mark the body part index needs updating
|
||||||
|
|
||||||
|
|
||||||
// The higher the nastiness likelihood the higher the change to get a painful and bloody wound
|
// Damage to limbs/head is scaled higher than torso by engine
|
||||||
private _nastinessLikelihood = linearConversion [0, 20, (_woundDamage / _thresholdWoundCount), 0.5, 30, true];
|
// Anything above this value is guaranteed worst wound possible
|
||||||
private _bleedingModifier = 0.25 + 8 * exp ((random [-4.5, -5, -6]) / _nastinessLikelihood);
|
private _worstDamage = [2, 1, 4, 4, 4, 4] select _bodyPartNToAdd;
|
||||||
private _painModifier = 0.05 + 2 * exp (-2 / _nastinessLikelihood);
|
|
||||||
|
|
||||||
private _bleeding = _injuryBleedingRate * _bleedingModifier;
|
// More wounds means more likely to get nasty wound
|
||||||
|
private _countModifier = 1 + random(_i - 1);
|
||||||
|
|
||||||
|
// Config specifies bleeding and pain for worst possible wound
|
||||||
|
// Worse wound correlates to higher damage, damage is not capped at 1
|
||||||
|
private _bleedModifier = linearConversion [0.1, _worstDamage, _woundDamage * _countModifier, 0.25, 1, true];
|
||||||
|
private _painModifier = (_bleedModifier * random [0.7, 1, 1.3]) min 1; // Pain isn't directly scaled to bleeding
|
||||||
|
|
||||||
|
private _bleeding = _injuryBleedingRate * _bleedModifier;
|
||||||
private _pain = _injuryPain * _painModifier;
|
private _pain = _injuryPain * _painModifier;
|
||||||
_painLevel = _painLevel + _pain;
|
_painLevel = _painLevel + _pain;
|
||||||
|
|
||||||
// wound category (minor [0..0.5], medium[0.5..1.0], large[1.0+])
|
// wound category (minor [0.25-0.5], medium [0.5-0.75], large [0.75+])
|
||||||
private _category = floor linearConversion [0, 1, _bleedingModifier, 0, 2, true];
|
private _category = floor linearConversion [0.25, 0.75, _bleedModifier, 0, 2, true];
|
||||||
|
|
||||||
private _classComplex = 10 * _woundClassIDToAdd + _category;
|
private _classComplex = 10 * _woundClassIDToAdd + _category;
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* 0: The Unit <OBJECT>
|
* 0: The Unit <OBJECT>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Total blood loss of unit <NUMBER>
|
* Total blood loss of unit (litres/second) <NUMBER>
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* [player] call ace_medical_status_fnc_getBloodLoss
|
* [player] call ace_medical_status_fnc_getBloodLoss
|
||||||
|
@ -17,10 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Value is taken because with cardic output and resistance at default values, it will put blood pressure High at 120.
|
// Value is taken because with cardic output and resistance at default values, it will put blood pressure High at 120.
|
||||||
#define MODIFIER_BP_HIGH 13.7142792
|
#define MODIFIER_BP_HIGH 9.4736842
|
||||||
|
|
||||||
// Value is taken because with cardic output and resistance at default values, it will put blood pressure Low at 80.
|
// Value is taken because with cardic output and resistance at default values, it will put blood pressure Low at 80.
|
||||||
#define MODIFIER_BP_LOW 9.1428528
|
#define MODIFIER_BP_LOW 6.3157894
|
||||||
|
|
||||||
params ["_unit"];
|
params ["_unit"];
|
||||||
|
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
/*
|
/*
|
||||||
* Author: Glowbal
|
* Author: Glowbal, SilentSpike
|
||||||
* Get the cardiac output from the Heart, based on current Heart Rate and Blood Volume.
|
* Get the cardiac output from the Heart, based on current Heart Rate and Blood Volume.
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: The Unit <OBJECT>
|
* 0: The Unit <OBJECT>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Current cardiac output (liter per second) <NUMBER>
|
* Current cardiac output (litre per second) <NUMBER>
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* [player] call ace_medical_status_fnc_getCardiacOutput
|
* [player] call ace_medical_status_fnc_getCardiacOutput
|
||||||
@ -20,13 +20,18 @@
|
|||||||
Source: http://en.wikipedia.org/wiki/Cardiac_output
|
Source: http://en.wikipedia.org/wiki/Cardiac_output
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// to limit the amount of complex calculations necessary, we take a set modifier to calculate Stroke Volume.
|
// Value taken from https://doi.org/10.1093%2Feurheartj%2Fehl336
|
||||||
#define MODIFIER_CARDIAC_OUTPUT 0.1904761
|
// as 94/95 ml ± 15 ml
|
||||||
|
#define VENTRICLE_STROKE_VOL 95e-3
|
||||||
|
|
||||||
params ["_unit"];
|
params ["_unit"];
|
||||||
|
|
||||||
private _bloodVolumeRatio = (GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME);
|
private _bloodVolumeRatio = GET_BLOOD_VOLUME(_unit) / DEFAULT_BLOOD_VOLUME;
|
||||||
private _heartRate = GET_HEART_RATE(_unit);
|
private _heartRate = GET_HEART_RATE(_unit);
|
||||||
private _cardiacOutput = ((_bloodVolumeRatio / MODIFIER_CARDIAC_OUTPUT) + ((_heartRate / DEFAULT_HEART_RATE) - 1)) / 60;
|
|
||||||
|
|
||||||
(0 max _cardiacOutput)
|
// Blood volume ratio dictates how much is entering the ventricle (this is an approximation)
|
||||||
|
private _entering = linearConversion [0.5, 1, _bloodVolumeRatio, 0, 1, true];
|
||||||
|
|
||||||
|
private _cardiacOutput = (_entering * VENTRICLE_STROKE_VOL) * _heartRate / 60;
|
||||||
|
|
||||||
|
0 max _cardiacOutput
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
* Author: Glowbal
|
* Author: Glowbal
|
||||||
* Update total wound bleeding based on open wounds and tourniquets
|
* Update total wound bleeding based on open wounds and tourniquets
|
||||||
|
* Wound bleeding = percentage of cardiac output lost
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: The Unit <OBJECT>
|
* 0: The Unit <OBJECT>
|
||||||
|
@ -32,12 +32,12 @@ if !IN_CRDC_ARRST(_unit) then {
|
|||||||
private _painLevel = GET_PAIN_PERCEIVED(_unit);
|
private _painLevel = GET_PAIN_PERCEIVED(_unit);
|
||||||
|
|
||||||
private _targetBP = 107;
|
private _targetBP = 107;
|
||||||
if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then {
|
if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then {
|
||||||
_targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME);
|
_targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME);
|
||||||
};
|
};
|
||||||
|
|
||||||
_targetHR = DEFAULT_HEART_RATE;
|
_targetHR = DEFAULT_HEART_RATE;
|
||||||
if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then {
|
if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then {
|
||||||
_targetHR = _heartRate * (_targetBP / (45 max _meanBP));
|
_targetHR = _heartRate * (_targetBP / (45 max _meanBP));
|
||||||
};
|
};
|
||||||
if (_painLevel > 0.2) then {
|
if (_painLevel > 0.2) then {
|
||||||
|
Loading…
Reference in New Issue
Block a user