Skip to content

Commit

Permalink
Medical Treatment - Extract stitching & trauma code (#10543)
Browse files Browse the repository at this point in the history
Co-authored-by: PabstMirror <[email protected]>
Co-authored-by: johnb432 <[email protected]>
  • Loading branch information
3 people authored Jan 13, 2025
1 parent 630c35b commit 77248d7
Show file tree
Hide file tree
Showing 19 changed files with 149 additions and 99 deletions.
2 changes: 1 addition & 1 deletion addons/medical/dev/watchVariable.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ GVAR(dev_watchVariableRunning) = true;
_return pushBack format [" - [Pain: %1] [Suppress: %2]", _pain toFixed 3, _painSuppress toFixed 3];

// Damage:
private _damage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _damage = GET_BODYPART_DAMAGE(_unit);
private _limping = ["", "[<t color ='#FFCC22'> Limping </t>]"] select (_unit getVariable [QEGVAR(medical,isLimping), false]);
_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];
Expand Down
4 changes: 2 additions & 2 deletions addons/medical/functions/fnc_addDamageToUnit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,14 @@ if (!isNull _instigator) then {
};

#ifdef DEBUG_TESTRESULTS
private _startDmg = +(_unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]);
private _startDmg = +GET_BODYPART_DAMAGE(_unit);
private _startPain = GET_PAIN(_unit);
#endif

[QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, _typeOfDamage]] call CBA_fnc_localEvent;

#ifdef DEBUG_TESTRESULTS
private _endDmg = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _endDmg = GET_BODYPART_DAMAGE(_unit);
private _endPain = GET_PAIN(_unit);
private _typeOfDamageAdj = _typeOfDamage call EFUNC(medical_damage,getTypeOfDamage);
private _config = configFile >> "ACE_Medical_Injuries" >> "damageTypes" >> _typeOfDamageAdj;
Expand Down
2 changes: 1 addition & 1 deletion addons/medical/functions/fnc_deserializeState.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private _state = [_json] call CBA_fnc_parseJSON;
[QEGVAR(medical,ivBags), nil],
[QEGVAR(medical,triageLevel), 0],
[QEGVAR(medical,triageCard), []],
[QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]
[VAR_BODYPART_DAMAGE, DEFAULT_BODYPART_DAMAGE_VALUES]
// Offset needs to be converted
// [VAR_MEDICATIONS, []]
];
Expand Down
2 changes: 1 addition & 1 deletion addons/medical/functions/fnc_serializeState.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private _state = [] call CBA_fnc_createNamespace;
[QEGVAR(medical,ivBags), nil],
[QEGVAR(medical,triageLevel), 0],
[QEGVAR(medical,triageCard), []],
[QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]
[VAR_BODYPART_DAMAGE, DEFAULT_BODYPART_DAMAGE_VALUES]
// Time needs to be converted
// [VAR_MEDICATIONS, []]
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
params ["_unit"];

private _painLevel = GET_PAIN_PERCEIVED(_unit);
private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _bodyPartDamage = GET_BODYPART_DAMAGE(_unit);

_bodyPartDamage params ["_headDamage", "_bodyDamage"];

Expand Down
4 changes: 2 additions & 2 deletions addons/medical_damage/functions/fnc_woundsHandlerBase.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private _createdWounds = false;
private _updateDamageEffects = false;
private _painLevel = 0;
private _criticalDamage = false;
private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _bodyPartDamage = GET_BODYPART_DAMAGE(_unit);
private _bodyPartVisParams = [_unit, false, false, false, false]; // params array for EFUNC(medical_engine,updateBodyPartVisuals);

// process wounds separately for each body part hit
Expand Down Expand Up @@ -197,7 +197,7 @@ if (_updateDamageEffects) then {

if (_createdWounds) then {
_unit setVariable [VAR_OPEN_WOUNDS, _openWounds, true];
_unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
_unit setVariable [VAR_BODYPART_DAMAGE, _bodyPartDamage, true];

_bodyPartVisParams call EFUNC(medical_engine,updateBodyPartVisuals);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
params ["_unit", "_updateHead", "_updateBody", "_updateArms", "_updateLegs"];
TRACE_5("updateBodyPartVisuals",_unit,_updateHead,_updateBody,_updateArms,_updateLegs);

private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _bodyPartDamage = GET_BODYPART_DAMAGE(_unit);

if (_updateHead) then {
[_unit, "head", (_bodyPartDamage select 0) > VISUAL_BODY_DAMAGE_THRESHOLD] call FUNC(damageBodyPart);
Expand Down
4 changes: 4 additions & 0 deletions addons/medical_engine/script_macros_medical.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@

#define DEFAULT_FRACTURE_VALUES [0,0,0,0,0,0]

#define DEFAULT_BODYPART_DAMAGE_VALUES [0,0,0,0,0,0]

// Triage colors, for consistency across UIs and functions
#define TRIAGE_COLOR_NONE 0, 0, 0, 0.9
#define TRIAGE_COLOR_MINIMAL 0, 0.5, 0, 0.9
Expand Down Expand Up @@ -168,6 +170,7 @@
#define VAR_OPEN_WOUNDS QEGVAR(medical,openWounds)
#define VAR_BANDAGED_WOUNDS QEGVAR(medical,bandagedWounds)
#define VAR_STITCHED_WOUNDS QEGVAR(medical,stitchedWounds)
#define VAR_BODYPART_DAMAGE QEGVAR(medical,bodyPartDamage)
// These variables track gradual adjustments (from medication, etc.)
#define VAR_MEDICATIONS QEGVAR(medical,medications)
// These variables track the current state of status values above
Expand Down Expand Up @@ -197,6 +200,7 @@
#define GET_BANDAGED_WOUNDS(unit) (unit getVariable [VAR_BANDAGED_WOUNDS, createHashMap])
#define GET_STITCHED_WOUNDS(unit) (unit getVariable [VAR_STITCHED_WOUNDS, createHashMap])
#define GET_DAMAGE_THRESHOLD(unit) (unit getVariable [QEGVAR(medical,damageThreshold), [EGVAR(medical,AIDamageThreshold),EGVAR(medical,playerDamageThreshold)] select (isPlayer unit)])
#define GET_BODYPART_DAMAGE(unit) (unit getVariable [VAR_BODYPART_DAMAGE, DEFAULT_BODYPART_DAMAGE_VALUES])

// The following function calls are defined here just for consistency
#define GET_BLOOD_LOSS(unit) ([unit] call EFUNC(medical_status,getBloodLoss))
Expand Down
2 changes: 1 addition & 1 deletion addons/medical_gui/functions/fnc_updateBodyImage.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ params ["_ctrlGroup", "_target", "_selectionN"];
// Get tourniquets, damage, and blood loss for target
private _tourniquets = GET_TOURNIQUETS(_target);
private _fractures = GET_FRACTURES(_target);
private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0, 0, 0, 0, 0, 0]];
private _bodyPartDamage = GET_BODYPART_DAMAGE(_target);
private _damageThreshold = GET_DAMAGE_THRESHOLD(_target);
private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0];

Expand Down
2 changes: 1 addition & 1 deletion addons/medical_gui/functions/fnc_updateInjuryList.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ _entries pushBack [localize _bodyPartName, [1, 1, 1, 1]];

// Damage taken tooltip
if (GVAR(showDamageEntry)) then {
private _bodyPartDamage = (_target getVariable [QEGVAR(medical,bodyPartDamage), [0, 0, 0, 0, 0, 0]]) select _selectionN;
private _bodyPartDamage = GET_BODYPART_DAMAGE(_target) select _selectionN;
if (_bodyPartDamage > 0) then {
private _damageThreshold = GET_DAMAGE_THRESHOLD(_target);
switch (true) do {
Expand Down
2 changes: 1 addition & 1 deletion addons/medical_status/functions/fnc_initUnit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ if (_isRespawn) then {
_unit setVariable [QEGVAR(medical,triageCard), [], true];

// Damage storage
_unit setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true];
_unit setVariable [VAR_BODYPART_DAMAGE, DEFAULT_BODYPART_DAMAGE_VALUES, true];

// Medication
_unit setVariable [VAR_MEDICATIONS, [], true];
Expand Down
2 changes: 2 additions & 0 deletions addons/medical_treatment/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PREP(addLoadPatientActions);
PREP(addToLog);
PREP(addToTriageCard);
PREP(addTrauma);
PREP(bandage);
PREP(bandageLocal);
PREP(bodyCleanupLoop);
Expand Down Expand Up @@ -58,6 +59,7 @@ PREP(scanMedicalItems);
PREP(setTriageStatus);
PREP(splint);
PREP(splintLocal);
PREP(stitchWound);
PREP(surgicalKitProgress);
PREP(surgicalKitStart);
PREP(tourniquet);
Expand Down
43 changes: 43 additions & 0 deletions addons/medical_treatment/functions/fnc_addTrauma.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#include "..\script_component.hpp"
/*
* Author: LinkIsGrim
* Add trauma to a body part.
*
* Arguments:
* 0: Patient <OBJECT>
* 1: Body Part <STRING>
* 2: Amount of trauma to add, negative to remove <NUMBER>
*
* Return Value:
* None
*
* Example:
* [player, "head", -5] call ace_medical_treatment_fnc_addTrauma
*
* Public: No
*/

params ["_unit", "_bodyPart", "_trauma"];

private _partIndex = ALL_BODY_PARTS find _bodyPart;
private _bodyPartDamage = GET_BODYPART_DAMAGE(_unit);
private _newDam = (_bodyPartDamage select _partIndex) + _trauma;

// Prevent obscenely small damage from lack of floating precision
if (_trauma < 0 && _newDam < 0.05) then {
_bodyPartDamage set [_partIndex, 0];
} else {
_bodyPartDamage set [_partIndex, _newDam];
};

// Update body part visuals
switch (_bodyPart) do {
case "head": { [_unit, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case "body": { [_unit, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case "leftarm";
case "rightarm": { [_unit, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
default { [_unit, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); };
};

TRACE_2("trauma - added damage",_trauma,_newDam);
_unit setVariable [VAR_BODYPART_DAMAGE, _bodyPartDamage, true];
23 changes: 2 additions & 21 deletions addons/medical_treatment/functions/fnc_bandageLocal.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -72,27 +72,8 @@ if (
};

if (GVAR(clearTrauma) == 2) then {
TRACE_2("clearTrauma - clearing trauma after bandage",_bodyPart,_openWounds);
private _partIndex = ALL_BODY_PARTS find _bodyPart;
private _bodyPartDamage = _patient getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _newDam = (_bodyPartDamage select _partIndex) - _treatedDamage;

// Prevent obscenely small damage from lack of floating precision
if (_newDam < 0.05) then {
_bodyPartDamage set [_partIndex, 0];
} else {
_bodyPartDamage set [_partIndex, _newDam];
};
_patient setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];
TRACE_2("clearTrauma - healed damage",_partIndex,_treatedDamage);

switch (_bodyPart) do {
case "head": { [_patient, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case "body": { [_patient, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case "leftarm";
case "rightarm": { [_patient, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
default { [_patient, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); };
};
TRACE_2("trauma - clearing trauma after bandage",_bodyPart,_woundsOnPart);
[_patient, _bodyPart, -_treatedDamage] call FUNC(addTrauma);
};

// Reset treatment condition cache for nearby players if we stopped all bleeding
Expand Down
2 changes: 1 addition & 1 deletion addons/medical_treatment/functions/fnc_fullHealLocal.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ _patient setVariable [VAR_OXYGEN_DEMAND, 0, true];
_patient setVariable [QEGVAR(medical,ivBags), nil, true];

// Damage storage
_patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true];
_patient setVariable [VAR_BODYPART_DAMAGE, DEFAULT_BODYPART_DAMAGE_VALUES, true];

// wakeup needs to be done after achieving stable vitals, but before manually reseting unconc var
if IS_UNCONSCIOUS(_patient) then {
Expand Down
2 changes: 1 addition & 1 deletion addons/medical_treatment/functions/fnc_getHealTime.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ private _bodyPartDamage = 0;

{
_bodyPartDamage = _bodyPartDamage + _x;
} forEach (_patient getVariable [QEGVAR(medical,bodyPartDamage), []]);
} forEach GET_BODYPART_DAMAGE(_patient);

10 max (((_bodyPartDamage * DAMAGE_SCALING_FACTOR) min 180) * GVAR(timeCoefficientPAK))
19 changes: 3 additions & 16 deletions addons/medical_treatment/functions/fnc_handleBandageOpening.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ if (random 1 <= _reopeningChance * GVAR(woundReopenChance)) then {
_injury params ["_classID"];

private _selectedInjury = _woundsOnPart select _injuryIndex;
_selectedInjury params ["_selClassID", "_selAmmount"];
_selectedInjury params ["_selClassID", "_selAmount", "", "_selDamage"];
if (_selClassID == _classID) then { // matching the IDs
private _bandagedWounds = GET_BANDAGED_WOUNDS(_target);
private _exist = false;
Expand All @@ -113,7 +113,7 @@ if (random 1 <= _reopeningChance * GVAR(woundReopenChance)) then {

if (_exist) then {
TRACE_2("Reopening Wound",_bandagedWounds,_openWounds);
_selectedInjury set [1, _selAmmount + _impact];
_selectedInjury set [1, _selAmount + _impact];
_target setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true];
_target setVariable [VAR_OPEN_WOUNDS, _openWounds, true];

Expand All @@ -123,20 +123,7 @@ if (random 1 <= _reopeningChance * GVAR(woundReopenChance)) then {

// Re-add trauma and damage visuals
if (GVAR(clearTrauma) == 2) then {
private _injuryDamage = (_selectedInjury select 4) * _impact;
private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
private _newDam = (_bodyPartDamage select _partIndex) + _injuryDamage;
_bodyPartDamage set [_partIndex, _newDam];

_target setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true];

switch (_partIndex) do {
case 0: { [_target, true, false, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case 1: { [_target, false, true, false, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
case 2;
case 3: { [_target, false, false, true, false] call EFUNC(medical_engine,updateBodyPartVisuals); };
default { [_target, false, false, false, true] call EFUNC(medical_engine,updateBodyPartVisuals); };
};
[_target, _part, _selDamage * _impact] call FUNC(addTrauma);
};

// Check if we gained limping from this wound re-opening
Expand Down
75 changes: 75 additions & 0 deletions addons/medical_treatment/functions/fnc_stitchWound.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include "..\script_component.hpp"
/*
* Author: BaerMitUmlaut, mharis001, LinkIsGrim
* Stitches a wound (either the first or a specific wound) from a body part.
*
* Arguments:
* 0: Patient <OBJECT>
* 1: Body Part <STRING>
* 2: Wound Array, will close first wound on body part if empty <ARRAY> (default: [])
*
* Return Value:
* Wound was stitched <BOOL>
*
* Example:
* [player, "head"] call ace_medical_treatment_fnc_stitchWound
*
* Public: No
*/

params ["_patient", "_bodyPart", ["_treatedWound", []]];

private _bandagedWounds = GET_BANDAGED_WOUNDS(_patient);
private _bandagedWoundsOnPart = _bandagedWounds getOrDefault [_bodyPart, []];

// Get the first stitchable wound from bandaged wounds, or make sure the passed wound exists
private _bandagedIndex = (count _bandagedWoundsOnPart) - 1;
if (_treatedWound isEqualTo []) then {
_treatedWound = _bandagedWoundsOnPart param [_bandagedIndex, _treatedWound];
} else {
_bandagedIndex = _bandagedWoundsOnPart find _treatedWound;
};

// Wound doesn't exist or there are no bandaged wounds to stitch
if (_bandagedIndex == -1) exitWith {false};

// Remove the wound from bandagedWounds
_bandagedWoundsOnPart deleteAt _bandagedIndex;

_treatedWound params ["_treatedID", "_treatedAmountOf", "", "_treatedDamageOf"];

// Check if we need to add a new stitched wound or increase the amount of an existing one
private _stitchedWounds = GET_STITCHED_WOUNDS(_patient);
private _stitchedWoundsOnPart = _stitchedWounds getOrDefault [_bodyPart, [], true];

private _stitchedIndex = _stitchedWoundsOnPart findIf {
_x params ["_classID"];
_classID == _treatedID
};

if (_stitchedIndex == -1) then {
_stitchedWoundsOnPart pushBack _treatedWound;
} else {
private _wound = _stitchedWoundsOnPart select _stitchedIndex;
_wound set [1, (_wound select 1) + _treatedAmountOf];
};

if (GVAR(clearTrauma) == 1) then {
TRACE_2("trauma - clearing trauma after stitching",_bodyPart,_treatedWound);
[_patient, _bodyPart, -(_treatedDamageOf * _treatedAmountOf)] call FUNC(addTrauma);
};

_patient setVariable [VAR_BANDAGED_WOUNDS, _bandagedWounds, true];
_patient setVariable [VAR_STITCHED_WOUNDS, _stitchedWounds, true];

// Check if we fixed limping by stitching this wound (only for leg wounds)
if (
EGVAR(medical,limping) == 2
&& {_patient getVariable [QEGVAR(medical,isLimping), false]}
&& {_bodyPart in ["leftleg", "rightleg"]}
) then {
TRACE_3("Updating damage effects",_patient,_bodyPart,local _patient);
[QEGVAR(medical_engine,updateDamageEffects), _patient, _patient] call CBA_fnc_targetEvent;
};

true // return
Loading

0 comments on commit 77248d7

Please sign in to comment.