Simplified damage storage

This commit is contained in:
ulteq 2016-12-08 11:38:43 +01:00
parent 627ea0ebdc
commit 78bfc0c26d
12 changed files with 80 additions and 93 deletions

View File

@ -57,24 +57,20 @@ class ACE_Settings {
typeName = "BOOL";
value = 1;
};
// Use those for handleIncapacitation?
class GVAR(playerDamageThreshold) {
category = CSTRING(Category_Medical);
displayName = CSTRING(MedicalSettings_playerDamageThreshold_DisplayName);
description = CSTRING(MedicalSettings_playerDamageThreshold_Description);
typeName = "SCALAR";
value = 1;
value = 1.05;
};
class GVAR(AIDamageThreshold) {
category = CSTRING(Category_Medical);
displayName = CSTRING(MedicalSettings_AIDamageThreshold_DisplayName);
description = CSTRING(MedicalSettings_AIDamageThreshold_Description);
typeName = "SCALAR";
value = 1;
value = 1.05;
};
class GVAR(enableUnconsciousnessAI) {
category = CSTRING(Category_Medical);
displayName = CSTRING(MedicalSettings_enableUnconsciousnessAI_DisplayName);

View File

@ -78,13 +78,12 @@ if (_show == 1) then {
private _selectionTourniquet = _target getVariable [QEGVAR(medical,tourniquets), [0,0,0,0,0,0]];
private _selectionBloodLoss = [0, 0, 0, 0, 0, 0];
private _selectionDamage = [0, 0, 0, 0, 0, 0];
private _selectionDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _allInjuryTexts = [];
{
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding", "_damage"];
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding"];
_selectionBloodLoss set [_bodyPartN, (_selectionBloodLoss select _bodyPartN) + (20 * (_bleeding * _amountOf))];
_selectionDamage set [_bodyPartN, (_selectionDamage select _bodyPartN) + _damage];
if (_selectionN == _bodyPartN) then {
// Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this]
if (_amountOf > 0) then {
@ -101,8 +100,7 @@ if (_show == 1) then {
} forEach (_target getVariable [QEGVAR(medical,openWounds), []]);
{
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding", "_damage"];
_selectionDamage set [_bodyPartN, (_selectionDamage select _bodyPartN) + _damage];
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding"];
if (_selectionN == _bodyPartN) then {
// Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this]
if (_amountOf > 0) then {
@ -119,8 +117,7 @@ if (_show == 1) then {
} forEach (_target getVariable [QEGVAR(medical,bandagedWounds), []]);
{
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding", "_damage"];
_selectionDamage set [_bodyPartN, (_selectionDamage select _bodyPartN) + _damage];
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding"];
if (_selectionN == _bodyPartN) then {
// Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this]
if (_amountOf > 0) then {

View File

@ -15,28 +15,28 @@
params ["_unit"];
private _painLevel = [_unit] call FUNC(getPainLevel);
private _headDamage = 0;
private _bodyDamage = 0;
private _bodyPartDamage = _unit getVariable [QGVAR(bodyPartDamage), [0,0,0,0,0,0]];
_bodyPartDamage params ["_headDamage", "_bodyDamage", "_leftArmDamage", "_rightArmDamage", "_leftLegDamage", "_rightLegDamage"];
// Exclude non penetrating body damage
{
_x params ["", "", "_bodyPart", "", "", "_damage"];
switch (_bodyPart) do {
case 0: {
_headDamage = _headDamage + _damage;
};
case 1: {
if (_damage > PENETRATION_THRESHOLD) then {
_bodyDamage = _bodyDamage + _damage;
};
};
_x params ["", "", "_bodyPartN", "", "", "_damage"];
if (_bodyPartN == 1 && {_damage < PENETRATION_THRESHOLD}) then {
_bodyDamage = _bodyDamage - _damage;
};
} forEach (_unit getVariable [QGVAR(openWounds), []]);
// todo: use an ace settings for the thresholds
if (_headDamage > 0.50) then {
private _damageThreshold = if (isPlayer _unit) then {
GVAR(playerDamageThreshold)
} else {
GVAR(AIDamageThreshold)
};
if (_headDamage > _damageThreshold / 2) then {
[QGVAR(CriticalInjury), _unit] call CBA_fnc_localEvent;
};
if (_bodyDamage > 1.05) then {
if (_bodyDamage > _damageThreshold) then {
[QGVAR(CriticalInjury), _unit] call CBA_fnc_localEvent;
};

View File

@ -47,7 +47,10 @@ _unit setVariable [QGVAR(triageCard), [], true];
_unit setVariable [QGVAR(ivBags), nil, true];
// damage storage
_unit setVariable [QGVAR(bodyPartDamage), [0,0,0,0,0,0], true];
#ifdef DEBUG_TESTRESULTS
_unit setVariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0], true];
#endif
// generic medical admin
_unit setVariable [QGVAR(inCardiacArrest), false, true];

View File

@ -35,12 +35,17 @@
// --- pain
#define PAIN_UNCONSCIOUS 0.5
// duration in seconds to stay knocked out due to pain
#define PAIN_KNOCK_OUT_DURATION (5 + random 10)
// Pain reduction per second
#define PAIN_REDUCTION_SPEED 0.001
// Chance to wake up when vitals are stable (checked once every SPONTANEOUS_WAKE_UP_INTERVAL seconds)
#define SPONTANEOUS_WAKE_UP_CHANCE 0.2
#define SPONTANEOUS_WAKE_UP_INTERVAL 15
#define LETHAL_HEAD_DAMAGE_THRESHOLD 1.0
// Minimum leg damage required for limping
#define LIMPING_DAMAGE_THRESHOLD 0.30
// Minimum body part damage required for blood effect on uniform
#define VISUAL_BODY_DAMAGE_THRESHOLD 0.35

View File

@ -38,9 +38,12 @@ call compile _extensionOutput;
// todo: Make the pain and bleeding calculations part of the extension again
private _painLevel = 0;
private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
{
_x params ["", "_woundClassIDToAdd", "_bodyPartNToAdd", "", "_bleeding"];
_bodyPartDamage set [_bodyPartNToAdd, (_bodyPartDamage select _bodyPartNToAdd) + _damage];
// The higher the nastiness likelihood the higher the change to get a painful and bloody wound
private _nastinessLikelihood = if (_damage > 1) then {
(_damage ^ 0.33)
@ -49,26 +52,26 @@ private _painLevel = 0;
};
private _bloodiness = 0.01 + 0.99 * (1 - random[0, 1, 0.9]) ^ (1 / _nastinessLikelihood);
private _painfullness = 0.05 + 0.95 * (1 - random[0, 1, 0.5]) ^ (1 / _nastinessLikelihood);
_bleeding = _bleeding * _bloodiness;
_x set [4, _bleeding];
_x set [5, _damage];
private _pain = ((GVAR(woundsData) select _woundClassIDToAdd) select 3) * _painfullness;
_painLevel = _painLevel max _pain;
#ifdef DEBUG_MODE_FULL
systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, round(_damage * 100) / 100, _damage > PENETRATION_THRESHOLD, round(_bleeding * 1000) / 1000, round(_pain * 1000) / 1000];
#endif
if (_bodyPartNToAdd == 0 && {_damage > 1}) then {
if (_bodyPartNToAdd == 0 && {_damage > LETHAL_HEAD_DAMAGE_THRESHOLD}) then {
[QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent;
};
// todo `forceWalk` based on leg damage
private _causeLimping = (GVAR(woundsData) select _woundClassIDToAdd) select 7;
if (_causeLimping == 1 && {_damage > 0.3} && {_bodyPartNToAdd > 3}) then {
if (_causeLimping == 1 && {_damage > LIMPING_DAMAGE_THRESHOLD} && {_bodyPartNToAdd > 3}) then {
[_unit, true] call EFUNC(medical_engine,setLimping);
};
@ -76,6 +79,7 @@ private _painLevel = 0;
} forEach _woundsCreated;
_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true];
_unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
[_unit, _bodyPart] call EFUNC(medical_engine,updateBodyPartVisuals);

View File

@ -73,8 +73,8 @@ private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []];
private _woundID = _unit getVariable [QGVAR(lastUniqueWoundID), 1];
private _painLevel = 0;
private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _woundsCreated = [];
{
if (_x select 0 <= _damage) exitWith {
for "_i" from 0 to ((_x select 1)-1) do {
@ -89,6 +89,8 @@ private _woundsCreated = [];
private _bodyPartNToAdd = [floor random 6, _bodyPartN] select _isSelectionSpecific; // 6 == count ALL_BODY_PARTS
_bodyPartDamage set [_bodyPartNToAdd, (_bodyPartDamage select _bodyPartNToAdd) + _damage];
// Create a new injury. Format [ID, classID, bodypart, percentage treated, bleeding rate]
_injury = [_woundID, _woundClassIDToAdd, _bodyPartNToAdd, 1, _injuryBleedingRate];
@ -113,13 +115,13 @@ private _woundsCreated = [];
systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, round(_damage * 100) / 100, _damage > PENETRATION_THRESHOLD, round(_bleeding * 1000) / 1000, round(_pain * 1000) / 1000];
#endif
if (_bodyPartNToAdd == 0 && {_damage > 1}) then {
if (_bodyPartNToAdd == 0 && {_damage > LETHAL_HEAD_DAMAGE_THRESHOLD}) then {
[QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent;
};
// todo `forceWalk` based on leg damage
private _causeLimping = (GVAR(woundsData) select _woundClassIDToAdd) select 7;
if (_causeLimping == 1 && {_damage > 0.3} && {_bodyPartNToAdd > 3}) then {
if (_causeLimping == 1 && {_damage > LIMPING_DAMAGE_THRESHOLD} && {_bodyPartNToAdd > 3}) then {
[_unit, true] call EFUNC(medical_engine,setLimping);
};
@ -136,6 +138,7 @@ private _woundsCreated = [];
} forEach _thresholds;
_unit setVariable [QEGVAR(medical,openWounds), _openWounds, true];
_unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
[_unit, _bodyPart] call EFUNC(medical_engine,updateBodyPartVisuals);

View File

@ -43,23 +43,13 @@ switch (toLower _bodyPart) do {
};
};
private _openWounds = _unit getVariable QEGVAR(medical,openWounds);
private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _damageOnAffectedBodyParts = 0;
{
private _damageOnBodyPart = 0;
private _partIndex = ALL_BODY_PARTS find toLower _x;
{
_x params ["", "", "_bodyPartN", "", "_bleeding", "_damage"];
if (_bodyPartN isEqualTo _partIndex) then {
_damageOnBodyPart = _damageOnBodyPart + _damage;
};
} forEach _openWounds;
private _damageOnBodyPart = _bodyPartDamage select _partIndex;
// report maximum of both legs or arms
_damageOnAffectedBodyParts = _damageOnAffectedBodyParts max _damageOnBodyPart;
} forEach _affectedBodyParts;
[_unit, _bodyPart, _damageOnAffectedBodyParts > 0.35] call FUNC(damageBodyPart);
[_unit, _bodyPart, _damageOnAffectedBodyParts > VISUAL_BODY_DAMAGE_THRESHOLD] call FUNC(damageBodyPart);

View File

@ -56,13 +56,12 @@ if (_totalIvVolume >= 1) then {
private _selectionTourniquet = _target getVariable [QEGVAR(medical,tourniquets), [0,0,0,0,0,0]];
private _selectionBloodLoss = [0, 0, 0, 0, 0, 0];
private _selectionDamage = [0, 0, 0, 0, 0, 0];
private _selectionDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _allInjuryTexts = [];
{
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding", "_damage"];
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding"];
_selectionBloodLoss set [_bodyPartN, (_selectionBloodLoss select _bodyPartN) + (20 * (_bleeding * _amountOf))];
_selectionDamage set [_bodyPartN, (_selectionDamage select _bodyPartN) + _damage];
if (_selectionN == _bodyPartN) then {
// Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this]
if (_amountOf > 0) then {
@ -79,8 +78,7 @@ private _allInjuryTexts = [];
} forEach (_target getVariable [QEGVAR(medical,openWounds), []]);
{
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding", "_damage"];
_selectionDamage set [_bodyPartN, (_selectionDamage select _bodyPartN) + _damage];
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding"];
if (_selectionN == _bodyPartN) then {
// Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this]
if (_amountOf > 0) then {
@ -97,8 +95,7 @@ private _allInjuryTexts = [];
} forEach (_target getVariable [QEGVAR(medical,bandagedWounds), []]);
{
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding", "_damage"];
_selectionDamage set [_bodyPartN, (_selectionDamage select _bodyPartN) + _damage];
_x params ["", "_woundClassID", "_bodyPartN", "_amountOf", "_bleeding"];
if (_selectionN == _bodyPartN) then {
// Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this]
if (_amountOf > 0) then {

View File

@ -75,7 +75,7 @@ class GVAR(Actions) {
displayNameProgress = ECSTRING(medical,Applying_Tourniquet);
allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"};
items[] = {"ACE_tourniquet"};
treatmentTime = 6;
treatmentTime = 7;
callbackSuccess = QFUNC(treatmentTourniquet);
condition = QUOTE(EGVAR(medical,advancedBandages) && {!([ARR_2(_target,_bodyPart)] call EFUNC(medical,hasTourniquetAppliedTo))});
litter[] = {};

View File

@ -34,35 +34,24 @@ if (_partialHeal) then {
private _partialHealCounter = _target getVariable [QGVAR(partialHealCounter), 0];
_partialHealCounter = _partialHealCounter + 1;
_target setVariable [QGVAR(partialHealCounter), _partialHealCounter, true];
private _effectiveness = (0 max EGVAR(medical,fieldEffectiveness_PAK) min 1) ^ _partialHealCounter;
private _persistentDamage = 1 - _effectiveness;
private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []];
{
_x params ["", "", "", "", "_bleeding", "_damage"];
_x set [5, _damage min _persistentDamage];
} forEach _openWounds;
_target setVariable [QEGVAR(medical,openWounds), _openWounds, true];
private _bandagedWounds = _target getVariable [QEGVAR(medical,bandagedWounds), []];
{
_x params ["", "", "", "", "_bleeding", "_damage"];
_x set [5, _damage min _persistentDamage];
} forEach _bandagedWounds;
_target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true];
private _stitchedWounds = _target getVariable [QEGVAR(medical,stitchedWounds), []];
{
_x params ["", "", "", "", "_bleeding", "_damage"];
_x set [5, _damage min _persistentDamage];
} forEach _stitchedWounds;
_target setVariable [QEGVAR(medical,stitchedWounds), _stitchedWounds, true];
// todo: only reset limping if leg damage was reduced enough
[_unit, false] call EFUNC(medical_engine,setLimping);
_target setDamage ((damage _target) min _persistentDamage);
private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
_bodyPartDamage = _bodyPartDamage apply {
(_x min _persistentDamage)
};
_target setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
if ((_bodyPartDamage select 4) < 0.3 && {(_bodyPartDamage select 5) < 0.3}) then {
[_unit, false] call EFUNC(medical_engine,setLimping);
};
// wounds and injuries
_target setVariable [QEGVAR(medical,openWounds), [], true];
_target setVariable [QEGVAR(medical,bandagedWounds), [], true];
_target setVariable [QEGVAR(medical,stitchedWounds), [], true];
} else {
_target setVariable [QEGVAR(medical,pain), 0, true];
_target setVariable [QEGVAR(medical,bloodVolume), DEFAULT_BLOOD_VOLUME, true];
@ -86,7 +75,10 @@ if (_partialHeal) then {
_target setVariable [QEGVAR(medical,ivBags), nil, true];
// damage storage
_target setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true];
#ifdef DEBUG_TESTRESULTS
_target setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true];
#endif
// generic medical admin
_target setVariable [QEGVAR(medical,inCardiacArrest), false, true];
@ -106,11 +98,11 @@ if (_partialHeal) then {
} forEach _allUsedMedication;
[_unit, false] call EFUNC(medical_engine,setLimping);
// Resetting damage
_target setDamage 0;
};
// Resetting damage
_target setDamage 0;
[QEGVAR(medical,FullHeal), _target] call CBA_fnc_localEvent;
[_target, "activity", ELSTRING(medical,Activity_fullHeal), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);

View File

@ -21,6 +21,6 @@ private _totalDamage = 0;
{
_totalDamage = _totalDamage + _x;
} forEach (_unit getVariable [QEGVAR(medical,bodyPartStatus), []]);
} forEach (_unit getVariable [QEGVAR(medical,bodyPartDamage), []]);
10 max (_totalDamage * 10) min 120
10 max (_totalDamage * 10) min 180