Skip to content

Commit

Permalink
Add tourniquet effects
Browse files Browse the repository at this point in the history
  • Loading branch information
BlueTheKing committed Nov 25, 2023
1 parent 7e405a7 commit ac41e97
Show file tree
Hide file tree
Showing 9 changed files with 232 additions and 1 deletion.
8 changes: 8 additions & 0 deletions addons/misc/CfgFunctions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ class CfgFunctions {
};
};
};
class overwrite_ace_medical_engine {
tag = "ace_medical_engine";
class ace_medical_engine {
class updateDamageEffects {
file = QPATHTOF(functions\fnc_updateDamageEffects.sqf);
};
};
};
class overwrite_medical_treatment {
tag = "ace_medical_treatment";
class ace_medical_treatment {
Expand Down
2 changes: 2 additions & 0 deletions addons/misc/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ PREP(getMagazineAmmoCounts);
PREP(getUniqueItems);
PREP(groupID);
PREP(handleRespawn);
PREP(handleTourniquetEffects);
PREP(handleUnconscious);
PREP(hasItem);
PREP(hasStableVitals);
Expand All @@ -50,4 +51,5 @@ PREP(treatmentIV);
PREP(treatmentSuccess);
PREP(unloadAndCarryPatient);
PREP(unSlingArmband);
PREP(updateDamageEffects);
PREP(useItem);
16 changes: 15 additions & 1 deletion addons/misc/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,18 @@ if (GVAR(incompatibilityWarning)) then {
[_carrier, _target] call ACEFUNC(dragging,dropObject_carry);
}] call CBA_fnc_addEventHandler;

call FUNC(FAK_updateContents);
call FUNC(FAK_updateContents);

[QACEGVAR(medical_treatment,tourniquetLocal), LINKFUNC(handleTourniquetEffects)] call CBA_fnc_addEventHandler;

["baseline", {
private _activeTourniquets = GET_TOURNIQUETS(ACE_player);
((_activeTourniquets select 2) + (_activeTourniquets select 3) min 1);
}, QUOTE(ADDON)] call ACEFUNC(common,addSwayFactor);

["multiplier", {
private _activeTourniquets = GET_TOURNIQUETS(ACE_player);
if (ACE_player getVariable [QGVAR(Tourniquet_ArmNecrosis), 0] > 0) then {
(ACE_player getVariable [QGVAR(Tourniquet_ArmNecrosis), 0]) / 10
} else {0};
}, QUOTE(ADDON)] call ACEFUNC(common,addSwayFactor);
6 changes: 6 additions & 0 deletions addons/misc/functions/fnc_fullHealLocal.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ _unit setVariable [QEGVAR(surgery,lidocaine), false, true];
_unit setVariable [QEGVAR(surgery,etomidate), false, true];
_unit setVariable [QEGVAR(surgery,sedated), false, true];

// KAT Misc
_unit setVariable [QGVAR(Tourniquet_ArmNecrosis), 0];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis), 0];
_unit setVariable [QGVAR(Tourniquet_PFH), -1];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0, true];

// Damage storage
_unit setVariable [QACEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true];

Expand Down
5 changes: 5 additions & 0 deletions addons/misc/functions/fnc_handleRespawn.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ _unit setVariable [QEGVAR(misc,isRightArmFree), true, true];
_unit setVariable [QEGVAR(misc,isLeftLegFree), true, true];
_unit setVariable [QEGVAR(misc,isRightLegFree), true, true];

_unit setVariable [QGVAR(Tourniquet_ArmNecrosis), 0];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis), 0];
_unit setVariable [QGVAR(Tourniquet_PFH), -1];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0, true];

// KAT Pharmacy

_unit setVariable [QEGVAR(pharma,alphaAction), 1, true];
Expand Down
90 changes: 90 additions & 0 deletions addons/misc/functions/fnc_handleTourniquetEffects.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "..\script_component.hpp"
/*
* Author: Blue
* Handle effects for when tourniquet is applied for prolonged time
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player] call kat_misc_fnc_handleTourniquetEffects;
*
* Public: No
*/

params ["_unit"];

if (_unit getVariable [QGVAR(Tourniquet_PFH), -1] != -1) exitWith {};
_unit setVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0, true];

private _handleLegEffects = {
params ["_unit", "_threshold"];

if (_unit getVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0] != _threshold) then {
_unit setVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), _threshold, true];
[_unit] call FUNC(updateDamageEffects);
};
};

private _tourniquetPFH = [{
params ["_args", "_idPFH"];
_args params ["_unit", "_handleLegEffects"];

private _tourniquet_ArmNecrosis = _unit getVariable [QGVAR(Tourniquet_ArmNecrosis), 0];
private _tourniquet_LegNecrosis = _unit getVariable [QGVAR(Tourniquet_LegNecrosis), 0];

private _activeTourniquets = GET_TOURNIQUETS(_unit);
private _armTourniquets = (_activeTourniquets select 2) + (_activeTourniquets select 3);
private _legTourniquets = (_activeTourniquets select 4) + (_activeTourniquets select 5);

if (_armTourniquets > 1) then {
_tourniquet_ArmNecrosis = _tourniquet_ArmNecrosis + 1.6; //0.15

if (_tourniquet_ArmNecrosis >= 100) then {
_tourniquet_ArmNecrosis = 100;
};
} else {
_tourniquet_ArmNecrosis = _tourniquet_ArmNecrosis - 3.2; //0.30

if (_tourniquet_ArmNecrosis <= 0) then {
_tourniquet_ArmNecrosis = 0;
};
};

if (_legTourniquets > 1) then {
_tourniquet_LegNecrosis = _tourniquet_LegNecrosis + 1.6;

if (_tourniquet_LegNecrosis >= 100) then {
_tourniquet_LegNecrosis = 100;
};
} else {
_tourniquet_LegNecrosis = _tourniquet_LegNecrosis - 3.2;

if (_tourniquet_LegNecrosis <= 0) then {
_tourniquet_LegNecrosis = 0;
};
};

switch (true) do {
case (_tourniquet_LegNecrosis > 20 && _tourniquet_LegNecrosis < 60): {[_unit, 20] call _handleLegEffects;};
case (_tourniquet_LegNecrosis > 60 && _tourniquet_LegNecrosis < 90): {[_unit, 60] call _handleLegEffects;};
case (_tourniquet_LegNecrosis > 90): {[_unit, 90] call _handleLegEffects;};
default {[_unit, 0] call _handleLegEffects;};
};

if ((_tourniquet_ArmNecrosis + _tourniquet_LegNecrosis <= 0 && _armTourniquets + _legTourniquets == 0) || !(alive _unit)) exitWith {
_unit setVariable [QGVAR(Tourniquet_ArmNecrosis), 0];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis), 0];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0, true];
_unit setVariable [QGVAR(Tourniquet_PFH), -1];
[_idPFH] call CBA_fnc_removePerFrameHandler;
};

_unit setVariable [QGVAR(Tourniquet_ArmNecrosis), _tourniquet_ArmNecrosis];
_unit setVariable [QGVAR(Tourniquet_LegNecrosis), _tourniquet_LegNecrosis];
}, 1, [_unit, _handleLegEffects]] call CBA_fnc_addPerFrameHandler;

_unit setVariable [QGVAR(Tourniquet_PFH), _tourniquetPFH];
102 changes: 102 additions & 0 deletions addons/misc/functions/fnc_updateDamageEffects.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#include "..\script_component.hpp"
/*
* Author: commy2, PabstMirror
* Modified: Blue
* Updates damage effects for limping and fractures.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player] call ace_medical_engine_fnc_updateDamageEffects
*
* Public: No
*/

params [["_unit", objNull, [objNull]]];

if (!local _unit) exitWith { ERROR_2("updateDamageEffects: Unit not local or null [%1:%2]",_unit,typeOf _unit); };

private _isLimping = false;
private _hasLegSplint = false;
private _noSprint = false;
private _noJog = false;

if (ACEGVAR(medical,fractures) > 0) then {
private _fractures = GET_FRACTURES(_unit);
TRACE_1("",_fractures);
if (((_fractures select 4) == 1) || {(_fractures select 5) == 1}) then {
TRACE_1("limping because of fracture",_fractures);
_isLimping = true;
};
private _aimFracture = 0;
if ((_fractures select 2) == 1) then { _aimFracture = _aimFracture + 4; };
if ((_fractures select 3) == 1) then { _aimFracture = _aimFracture + 4; };

if (ACEGVAR(medical,fractures) in [2, 3]) then { // the limp with a splint will still cause effects
// Block sprint / force walking based on fracture setting and leg splint status
_hasLegSplint = (_fractures select 4) == -1 || {(_fractures select 5) == -1};
if (ACEGVAR(medical,fractures) == 2) then {
_noSprint = _hasLegSplint;
} else {
_noJog = _hasLegSplint;
};

if ((_fractures select 2) == -1) then { _aimFracture = _aimFracture + 2; };
if ((_fractures select 3) == -1) then { _aimFracture = _aimFracture + 2; };
};
_unit setVariable [QACEGVAR(medical_engine,aimFracture), _aimFracture, false]; // local only var, used in ace_medical's postInit to set ACE_setCustomAimCoef
};

if (!_isLimping && {ACEGVAR(medical,limping) > 0}) then {
private _openWounds = GET_OPEN_WOUNDS(_unit);

// Want a copy of combined arrays to prevent wound mixing
private _legWounds = (_openWounds getOrDefault ["leftleg", []])
+ (_openWounds getOrDefault ["rightleg", []]);

if (ACEGVAR(medical,limping) == 2) then {
private _bandagedWounds = GET_BANDAGED_WOUNDS(_unit);
_legWounds = _legWounds
+ (_bandagedWounds getOrDefault ["leftleg", []])
+ (_bandagedWounds getOrDefault ["rightleg", []]);
};

{
_x params ["_xClassID", "_xAmountOf", "", "_xDamage"];
if (
(_xAmountOf > 0)
&& {_xDamage > LIMPING_DAMAGE_THRESHOLD_DEFAULT}
// select _causeLimping from woundDetails
&& {(ACEGVAR(medical_damage,woundDetails) get (_xClassID / 10)) select 3}
) exitWith {
TRACE_1("limping because of wound",_x);
_isLimping = true;
};
} forEach _legWounds;
};

if (_unit getVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0] >= 20) then {
_noSprint = true;
};

if (_unit getVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0] >= 60) then {
_noJog = true;
};

if (_unit getVariable [QGVAR(Tourniquet_LegNecrosis_Threshold), 0] >= 90) then {
_isLimping = true;
};

[_unit, "blockSprint", QACEGVAR(medical,fracture), _noSprint] call ACEFUNC(common,statusEffect_set);
[_unit, "forceWalk", QACEGVAR(medical,fracture), _noJog] call ACEFUNC(common,statusEffect_set);

_unit setVariable [QACEGVAR(medical,isLimping), _isLimping, true];

// refresh
private _isDamaged = _unit getHitPointDamage "HitLegs" >= DAMAGED_MIN_THRESHOLD && {_unit getHitPointDamage "HitLegs" != LIMPING_MIN_DAMAGE};

[_unit, "Legs", _isDamaged] call ACEFUNC(medical_engine,damageBodyPart);
3 changes: 3 additions & 0 deletions addons/misc/script_component.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@
#include "\x\kat\addons\main\script_macros.hpp"

#define MEDICAL_TREATMENT_ITEMS (call (uiNamespace getVariable [QACEGVAR(medical_treatment,treatmentItems), {[]}]))

#define DAMAGED_MIN_THRESHOLD 0.45
#define LIMPING_MIN_DAMAGE 0.5
1 change: 1 addition & 0 deletions addons/pharma/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PREP(fluid);
PREP(fluidLocal);
PREP(getBloodLoss);
PREP(getBloodVolumeChange);
PREP(tourniquetRemove);
PREP(init);
PREP(inspectCatheter);
PREP(medication);
Expand Down

0 comments on commit ac41e97

Please sign in to comment.