From 81d0a338cee677c2341f90e71a3b5a8e5dbca7f7 Mon Sep 17 00:00:00 2001 From: freghar Date: Fri, 4 Nov 2022 23:48:30 +0000 Subject: [PATCH 1/4] ace_medical_tweaks: restore hitpoints on stitch Signed-off-by: freghar --- .../custom_hasStableVitals.sqf | 17 ++++- .../heal_hitpoints/config.cpp | 43 ++++++++++++ .../heal_hitpoints/custom_updateBodyImage.sqf | 44 ++++++++++++ .../heal_hitpoints/fn_init.sqf | 13 ++++ .../heal_hitpoints/fn_onStitch.sqf | 70 +++++++++++++++++++ 5 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 addons/ace_medical_tweaks/heal_hitpoints/config.cpp create mode 100644 addons/ace_medical_tweaks/heal_hitpoints/custom_updateBodyImage.sqf create mode 100644 addons/ace_medical_tweaks/heal_hitpoints/fn_init.sqf create mode 100644 addons/ace_medical_tweaks/heal_hitpoints/fn_onStitch.sqf diff --git a/addons/ace_medical_tweaks/custom_hasStableVitals.sqf b/addons/ace_medical_tweaks/custom_hasStableVitals.sqf index 874e1bb..e388b66 100644 --- a/addons/ace_medical_tweaks/custom_hasStableVitals.sqf +++ b/addons/ace_medical_tweaks/custom_hasStableVitals.sqf @@ -2,7 +2,18 @@ params ["_unit"]; -//if (GET_BLOOD_VOLUME(_unit) < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) exitWith { false }; +// if lost "a large amount of blood" +// && doesn't have epinephrine in the system || does and is unlucky, +// then do not wake up +// +// note that this assumes 100% wakeup chance *while epi is in the system* +// eg. maximum spontaneousWakeUpEpinephrineBoost, and this 100% is reduced +// further by the 'random' command +//if ( +// GET_BLOOD_VOLUME(_unit) < BLOOD_VOLUME_CLASS_3_HEMORRHAGE +// ) exitWith { false }; +//&& {[_unit, "Epinephrine"] call ace_medical_status_fnc_getMedicationCount == 0 || false} + if IN_CRDC_ARRST(_unit) exitWith { false }; //private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); @@ -11,9 +22,9 @@ if IN_CRDC_ARRST(_unit) exitWith { false }; private _bloodPressure = GET_BLOOD_PRESSURE(_unit); _bloodPressure params ["_bloodPressureL", "_bloodPressureH"]; -if (_bloodPressureL < 50 || {_bloodPressureH < 60}) exitWith { false }; +if (_bloodPressureL < 40 || {_bloodPressureH < 60}) exitWith { false }; private _heartRate = GET_HEART_RATE(_unit); if (_heartRate < 40) exitWith { false }; -true +true; diff --git a/addons/ace_medical_tweaks/heal_hitpoints/config.cpp b/addons/ace_medical_tweaks/heal_hitpoints/config.cpp new file mode 100644 index 0000000..fd5393d --- /dev/null +++ b/addons/ace_medical_tweaks/heal_hitpoints/config.cpp @@ -0,0 +1,43 @@ +class CfgPatches { + class cnto_ace_medical_tweaks_heal_hitpoints { + units[] = {}; + weapons[] = {}; + magazines[] = {}; + requiredAddons[] = { + "cba_events", + "cba_xeh", + "ace_medical", + "ace_medical_engine", + "ace_medical_gui", + "ace_medical_damage" + }; + }; +}; + +class CfgFunctions { + class cnto_ace_medical_tweaks_heal_hitpoints { + class all { + file = "\cnto\additions\ace_medical_tweaks\heal_hitpoints"; + class init; + class onStitch; + }; + class overriden { + class orig_updateBodyImage { + file = "z\ace\addons\medical_gui\functions\fnc_updateBodyImage.sqf"; + }; + }; + }; + class ace_medical_gui { + class all { + class updateBodyImage { + file = "\cnto\additions\ace_medical_tweaks\heal_hitpoints\custom_updateBodyImage.sqf"; + }; + }; + }; +}; + +class Extended_PreInit_EventHandlers { + class cnto_ace_medical_tweaks_heal_hitpoints { + init = "[] call cnto_ace_medical_tweaks_heal_hitpoints_fnc_init"; + }; +}; diff --git a/addons/ace_medical_tweaks/heal_hitpoints/custom_updateBodyImage.sqf b/addons/ace_medical_tweaks/heal_hitpoints/custom_updateBodyImage.sqf new file mode 100644 index 0000000..7b746bf --- /dev/null +++ b/addons/ace_medical_tweaks/heal_hitpoints/custom_updateBodyImage.sqf @@ -0,0 +1,44 @@ +#define PREFIX ace +#include "\x\cba\addons\main\script_macros_common.hpp" +#include "\z\ace\addons\medical_engine\script_macros_medical.hpp" + +params ["_ctrl", "_target"]; + +// collect damage/trauma from all wounds (used only for blue GUI coloring) +// +// this is basically the same as ACE natively calculating it for +// ace_medical_bodyPartDamage, except we can display it independently +// of the real ace_medical_bodyPartDamage set for the _target unit + +private _trauma = [0,0,0,0,0,0]; + +// count only fully auto-treated bruises, +// see fn_onStitch.sqf for the params +{ + _x params ["_classID", "_bodypartIndex", "_amountOf", "_bloodloss", "_damage"]; + if (_amountOf == 0) then { continue }; + private _wound_name = ace_medical_damage_woundClassNamesComplex select _classID; + if (_wound_name find "Contusion" == 0) then { + private _orig = _trauma select _bodypartIndex; + _trauma set [_bodypartIndex, _orig + _amountOf*_damage]; + }; +} forEach GET_OPEN_WOUNDS(_target); + +{ + _x params ["_classID", "_bodypartIndex", "_amountOf", "_bloodloss", "_damage"]; + private _orig = _trauma select _bodypartIndex; + _trauma set [_bodypartIndex, _orig + _amountOf*_damage]; +} forEach (GET_BANDAGED_WOUNDS(_target) + GET_STITCHED_WOUNDS(_target)); + +// the default is to use the darkest blue even for medium-ish +// wounds - tone it down, so darker blue is reserved only for +// heavier ones +_trauma = _trauma apply { _x * 0.3 }; + +// fool the original ACE updateBodyImage function +// by faking bodyPartDamage for the duration of the function run +// - this works reliably because we run unscheduled +private _backup = _target getVariable ["ace_medical_bodyPartDamage", [0,0,0,0,0,0]]; +_target setVariable ["ace_medical_bodyPartDamage", _trauma]; +_this call cnto_ace_medical_tweaks_heal_hitpoints_fnc_orig_updateBodyImage; +_target setVariable ["ace_medical_bodyPartDamage", _backup]; diff --git a/addons/ace_medical_tweaks/heal_hitpoints/fn_init.sqf b/addons/ace_medical_tweaks/heal_hitpoints/fn_init.sqf new file mode 100644 index 0000000..d07c07b --- /dev/null +++ b/addons/ace_medical_tweaks/heal_hitpoints/fn_init.sqf @@ -0,0 +1,13 @@ +["CBA_settingsInitialized", { + // just to make sure it's not enabled + ace_medical_treatment_clearTrauma = 0; +}] call CBA_fnc_addEventHandler; + +["ace_treatmentSucceded", { + params ["_medic", "_patient", "_bodyPart", "_classname"]; + if (_classname != "SurgicalKit") exitWith {}; + if (!local _patient) exitWith { + ["ace_treatmentSucceded", _this, _patient] call CBA_fnc_targetEvent; + }; + _patient call cnto_ace_medical_tweaks_heal_hitpoints_fnc_onStitch; +}] call CBA_fnc_addEventHandler; diff --git a/addons/ace_medical_tweaks/heal_hitpoints/fn_onStitch.sqf b/addons/ace_medical_tweaks/heal_hitpoints/fn_onStitch.sqf new file mode 100644 index 0000000..0261df0 --- /dev/null +++ b/addons/ace_medical_tweaks/heal_hitpoints/fn_onStitch.sqf @@ -0,0 +1,70 @@ +#define PREFIX ace +#include "\x\cba\addons\main\script_macros_common.hpp" +#include "\z\ace\addons\medical_engine\script_macros_medical.hpp" + +private _restore_hit_idx = [true,true,true,true,true,true]; + +// open wound entries persist even after bandaging/stitching +{ + _x params ["_classID", "_bodypartIndex", "_amountOf", "_bloodloss", "_damage"]; + + // bandaged/stitched, nothing open remains; + // used for partially bandaged wounds + if (_amountOf == 0) then { continue }; + + // don't ask me why + private _wound_name = ace_medical_damage_woundClassNamesComplex select _classID; + // treat bruises as always bandaged/stitched + if (_wound_name find "Contusion" == 0) then { continue }; + + // finally, an untreated open wound; + _restore_hit_idx set [_bodypartIndex, false]; +} forEach GET_OPEN_WOUNDS(_this); + +// bandaged wounds are easier - they disappear after stitching +{ + _x params ["_classID", "_bodypartIndex", "_amountOf", "_bloodloss", "_damage"]; + _restore_hit_idx set [_bodypartIndex, false]; +} forEach GET_BANDAGED_WOUNDS(_this); + + +// if a body part made it this far, it doesn't contain any +// unstitched wounds - restore lost trauma + +// restore vanilla game hitpoints + +private _current = _this getHitPointDamage "hitHead"; +if (_current > 0 && _restore_hit_idx select HITPOINT_INDEX_HEAD) then { + _this setHitPointDamage ["hitHead", 0]; +}; + +_current = _this getHitPointDamage "hitBody"; +if (_current > 0 && _restore_hit_idx select HITPOINT_INDEX_BODY) then { + _this setHitPointDamage ["hitBody", 0]; +}; + +_current = _this getHitPointDamage "hitHands"; +if (_current > 0 && _restore_hit_idx select HITPOINT_INDEX_LARM && _restore_hit_idx select HITPOINT_INDEX_RARM) then { + _this setHitPointDamage ["hitHands", 0]; +}; + +_current = _this getHitPointDamage "hitLegs"; +if (_current > 0 && _restore_hit_idx select HITPOINT_INDEX_LLEG && _restore_hit_idx select HITPOINT_INDEX_RLEG) then { + _this setHitPointDamage ["hitLegs", 0]; +}; + +// update ACE trauma + +private _ace_damage_old = _this getVariable ["ace_medical_bodyPartDamage", [0,0,0,0,0,0]]; +private _ace_damage_new = +_ace_damage_old; + +{ + if (_x) then { + _ace_damage_new set [_forEachIndex, 0]; + }; +} forEach _restore_hit_idx; + +// avoid unnecessary network traffic +if (_ace_damage_new isNotEqualTo _ace_damage_old) then { + _this setVariable ["ace_medical_bodyPartDamage", _ace_damage_new, true]; +}; From 6db86f493573879e46d52e4c815bda3fca5249e1 Mon Sep 17 00:00:00 2001 From: freghar Date: Fri, 4 Nov 2022 23:59:21 +0000 Subject: [PATCH 2/4] ace_medical_tweaks: avoid cardiac arrest on instant fatal damage Signed-off-by: freghar --- addons/ace_medical_tweaks/config.cpp | 51 +++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/addons/ace_medical_tweaks/config.cpp b/addons/ace_medical_tweaks/config.cpp index d0adfbf..f656b5c 100644 --- a/addons/ace_medical_tweaks/config.cpp +++ b/addons/ace_medical_tweaks/config.cpp @@ -6,7 +6,56 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredAddons[] = { - "ace_medical_status" + "ace_medical_status", + "ace_medical_statemachine", + "ace_medical_damage", + "ace_medical_treatment" + }; + }; +}; + +// avoid the cardiac arrest state when receiving would-be-fatal damage, +// forcing unconsciousness instead +// note that this doesn't disable cardiac arrest completely - other logic +// can still enter that state, ie. very low blood / vitals checking code +class ACE_Medical_StateMachine { + class Default { + class FatalVitals { + targetState = "Unconscious"; + events[] = {"ace_medical_FatalVitals"}; // split Bleedout + }; + class FatalInjury { + targetState = "Dead"; + //events[] = {QEGVAR(medical,FatalInjury)}; + }; + class Bleedout { + targetState = "Dead"; + events[] = {"ace_medical_Bleedout"}; + }; + }; + class Injured { + class FatalVitals { + targetState = "Unconscious"; + events[] = {"ace_medical_FatalVitals"}; // split Bleedout + }; + class FatalInjury { + targetState = "Dead"; + //events[] = {QEGVAR(medical,FatalInjury)}; + }; + class Bleedout { + targetState = "Dead"; + events[] = {"ace_medical_Bleedout"}; + }; + }; + class Unconscious { + delete FatalTransitions; + class FatalInjury { + targetState = "Dead"; + //events[] = {QEGVAR(medical,FatalInjury)}; + }; + class Bleedout { + targetState = "Dead"; + events[] = {"ace_medical_Bleedout"}; }; }; }; From e58b8ad5757616d34774a4d8cd16c823adc8c281 Mon Sep 17 00:00:00 2001 From: freghar Date: Sat, 5 Nov 2022 00:00:01 +0000 Subject: [PATCH 3/4] ace_medical_tweaks: use wound probabilities estimating ACE 3.14 This should revert the bruisepocalypse. Signed-off-by: freghar --- addons/ace_medical_tweaks/config.cpp | 59 ++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/addons/ace_medical_tweaks/config.cpp b/addons/ace_medical_tweaks/config.cpp index f656b5c..90e0736 100644 --- a/addons/ace_medical_tweaks/config.cpp +++ b/addons/ace_medical_tweaks/config.cpp @@ -60,6 +60,65 @@ class ACE_Medical_StateMachine { }; }; +class ACE_Medical_Injuries { + class wounds { + // make burns bleed a little bit, so they can be bandaged/stitched + // - unlike bruises, they don't produce other wounds that would bleed, + // and are rare enough to where bleeding probably doesn't matter + class ThermalBurn { + bleeding = 0.01; + }; + }; + class damageTypes { + // generally less wounds per bullet + class bullet { + //thresholds[] = {{20, 10}, {4.5, 2}, {3, 1}, {0, 1}}; + thresholds[] = {{20, 6}, {5, 1}, {0, 1}}; + delete Contusion; + }; + // notably less wounds per small explosive effect, but at least 1 + class grenade { + //thresholds[] = {{20, 10}, {10, 5}, {4, 3}, {1.5, 2}, {0.8, 2}, {0.3, 1}, {0, 0}}; + thresholds[] = {{20, 8}, {10, 3}, {4, 2}, {0.3, 1}, {0, 0}}; + class Contusion { weighting[] = {{0.5, 0}, {0.35, 0.2}}; }; + }; + // a lot of wounds for big damage, but very few for small damage + class explosive { + //thresholds[] = {{20, 15}, {8, 7}, {2, 3}, {1.2, 2}, {0.4, 1}, {0,0}}; + thresholds[] = {{20, 15}, {8, 4}, {0.4, 1}, {0, 0}}; + class Contusion { weighting[] = {{0.5, 0}, {0.35, 0.2}}; }; + }; + // shrapnel - same idea as explosive, but less wounds overall + class shell { + //thresholds[] = {{20, 10}, {10, 5}, {4.5, 2}, {2, 2}, {0.8, 1}, {0.2, 1}, {0, 0}}; + thresholds[] = {{20, 10}, {10, 3}, {4, 2}, {0.2, 1}, {0, 0}}; + class Cut { weighting[] = {{0.7, 0}, {0.35, 1}}; }; + class Contusion { weighting[] = {{0.5, 0}, {0.35, 0.2}}; }; + }; + class vehiclecrash { + delete Contusion; // due to discrete weight ranges + }; + class collision { + class Contusion { weighting[] = {{0.4, 0}, {0.2, 0.2}}; }; + }; + // fall damage - reduce overall bruise amount + class falling { + //thresholds[] = {{8, 4}, {1, 1}, {0.2, 1}, {0.1, 0.7}, {0, 0.5}}; + thresholds[] = {{8, 3}, {1, 1}, {0.2, 1}, {0.1, 0.7}, {0, 0.5}}; + class Contusion { weighting[] = {{0.4, 0}, {0.2, 0.2}}; }; + }; + // backblast - same idea as fall damage + class backblast { + //thresholds[] = {{1, 6}, {1, 5}, {0.55, 5}, {0.55, 2}, {0, 2}}; + thresholds[] = {{1, 3}, {0.55, 2}, {0, 1}}; + class Contusion { weighting[] = {{0.35, 0}, {0.35, 0.2}}; }; + }; + class punch { + class Contusion { weighting[] = {{0.35, 0}, {0.35, 0.2}}; }; + }; + }; +}; + /* * unconsciousness condition tweaks * From fbe3fb24a417fa10ffa1c60ad1e232fba3159f46 Mon Sep 17 00:00:00 2001 From: freghar Date: Sat, 5 Nov 2022 00:01:38 +0000 Subject: [PATCH 4/4] ace_medical_tweaks: make morphine's effect on HR less potent Signed-off-by: freghar --- addons/ace_medical_tweaks/config.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/addons/ace_medical_tweaks/config.cpp b/addons/ace_medical_tweaks/config.cpp index 90e0736..5944f8b 100644 --- a/addons/ace_medical_tweaks/config.cpp +++ b/addons/ace_medical_tweaks/config.cpp @@ -119,6 +119,20 @@ class ACE_Medical_Injuries { }; }; +class ace_medical_treatment { + class Medication { + class Morphine { + // lower the effect on heart rate, to avoid the need of many + // epinephrines to counter it + actually allow people to wake + // up without epinephrine use + hrIncreaseLow[] = {-1, -5}; + hrIncreaseNormal[] = {-3, -8}; + hrIncreaseHigh[] = {-6, -12}; + timeTillMaxEffect = 10; + }; + }; +}; + /* * unconsciousness condition tweaks *