diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index 5efc75b8df..fd2c12e2c5 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -19,8 +19,8 @@ //Status Effect EHs: [QGVAR(setStatusEffect), {_this call FUNC(statusEffect_set)}] call CBA_fnc_addEventHandler; -["forceWalk", false, ["ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches"]] call FUNC(statusEffect_addType); -["blockSprint", false, []] call FUNC(statusEffect_addType); +["forceWalk", false, ["ace_advanced_fatigue", "ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches"]] call FUNC(statusEffect_addType); +["blockSprint", false, ["ace_advanced_fatigue", "ace_medical_fracture"]] call FUNC(statusEffect_addType); ["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered)]] call FUNC(statusEffect_addType); ["blockDamage", false, ["fixCollision", "ACE_cargo"]] call FUNC(statusEffect_addType); ["blockEngine", false, ["ACE_Refuel"]] call FUNC(statusEffect_addType); diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index de20e13aef..c14d52649e 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -3,7 +3,8 @@ ["medical", { // Hide when patient display is up because they might overlap - if (!isNull EGVAR(medical_gui,displayPatientInformationTarget)) exitWith {""}; + private _display = uiNamespace getVariable [QEGVAR(medical_gui,RscPatientInfo), displayNull]; + if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; @@ -59,6 +60,10 @@ _return pushBack format ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2]; _return pushBack format ["[HHnd:%1] [HLeg: %2] %3", (_unit getHitPointDamage "HitHands") toFixed 2, (_unit getHitPointDamage "HitLegs") toFixed 2, _limping]; + private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]; + private _canSprint = if (isSprintAllowed _unit) then {""} else {"[Sprint Blocked]"}; + _return pushBack format ["Fractures: %1 %2", _fractures, _canSprint]; + // Tourniquets: _return pushBack "------- Tourniquets: -------"; diff --git a/addons/medical/initSettings.sqf b/addons/medical/initSettings.sqf index 0ae2c0e9f1..805b56e830 100644 --- a/addons/medical/initSettings.sqf +++ b/addons/medical/initSettings.sqf @@ -12,3 +12,23 @@ private _categoryArray = [LELSTRING(medical,Category_DisplayName), "?"]; {[QGVAR(spontaneousWakeUpChance), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart ] call CBA_settings_fnc_init; + +[ + QEGVAR(medical,limping), "LIST", + ["limping"],//LSTRING(limping_DisplayName), LSTRING(limping_Description)], + _categoryArray, + [[0,1,2],["Disabled", "Limp on open wound", "Limp on open or bandaged wound"], 1], // [values, titles, defaultIndex] + true, // isGlobal + {[QEGVAR(medical,limping), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; + +[ + QEGVAR(medical,fractures), "LIST", + ["fractures"],//LSTRING(limping_DisplayName), LSTRING(limping_Description)], + _categoryArray, + [[0,1,2],["Disabled", "Splints fully heal", "Splints heal (but cannot sprint)"], 1], // [values, titles, defaultIndex] + true, // isGlobal + {[QEGVAR(medical,fractures), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_settings_fnc_init; diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index ea15797cbe..9cdeb6d6a7 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -36,6 +36,7 @@ class ACE_Medical_Injuries { pain = 0.8; minDamage = 0.1; causeLimping = 1; + causeFracture = 1; }; // 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 { @@ -59,6 +60,7 @@ class ACE_Medical_Injuries { pain = 0.9; minDamage = 0.35; causeLimping = 1; + causeFracture = 1; }; // Deep, narrow wounds produced by sharp objects such as nails, knives, and broken glass. class PunctureWound { diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index 4f14c1cfdc..9a758a4498 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -18,7 +18,7 @@ private _injuriesConfigRoot = configFile >> "ACE_Medical_Injuries"; // --- parse wounds -GVAR(woundClassNames) = []; +GVAR(woundClassNamesComplex) = []; // index = 10 * classID + category; [will contain nils] e.g. ["aMinor", "aMed", "aLarge", nil, nil..."bMinor"] GVAR(woundsData) = []; // @todo classTypes are strings currently. Convert them to unqiue IDs instead. private _woundsConfig = _injuriesConfigRoot >> "wounds"; @@ -34,12 +34,15 @@ private _classID = 0; private _minDamage = GET_NUMBER(_entry >> "minDamage",0); private _maxDamage = GET_NUMBER(_entry >> "maxDamage",-1); private _causes = GET_ARRAY(_entry >> "causes",[]); - private _causeLimping = GET_NUMBER(_entry >> "causeLimping",0); - private _causeFracture = GET_NUMBER(_entry >> "causeFracture",0); + private _causeLimping = 1 == GET_NUMBER(_entry >> "causeLimping",0); + private _causeFracture = 1 == GET_NUMBER(_entry >> "causeFracture",0); if !(_causes isEqualTo []) then { GVAR(woundClassNames) pushBack _className; GVAR(woundsData) pushBack [_classID, _selections, _bleeding, _pain, [_minDamage, _maxDamage], _causes, _className, _causeLimping, _causeFracture]; + { + GVAR(woundClassNamesComplex) set [10 * _classID + _forEachIndex, format ["%1%2", _className, _x]]; + } forEach ["Minor", "Medium", "Large"]; _classID = _classID + 1; }; } forEach configProperties [_woundsConfig, "isClass _x"]; diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf index cf5e8bbeff..410a49fa8c 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf @@ -67,16 +67,17 @@ if (_highestPossibleSpot < 0) exitWith { TRACE_2("no wounds possible",_damage,_h // Administration for open wounds and ids private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []]; +private _updateLimping = false; private _painLevel = 0; private _critialDamage = false; private _bodyPartDamage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; private _bodyPartVisParams = [_unit, false, false, false, false]; // params array for EFUNC(medical_engine,updateBodyPartVisuals); -private _woundsCreated = []; + { _x params ["_thresholdMinDam", "_thresholdWoundCount"]; if (_thresholdMinDam <= _damage) exitWith { private _woundDamage = _damage / (_thresholdWoundCount max 1); // If the damage creates multiple wounds - for "_i" from 0 to (_thresholdWoundCount-1) do { + for "_i" from 1 to _thresholdWoundCount do { // Find the injury we are going to add. Format [ classID, allowdSelections, bleedingRate, injuryPain] private _oldInjury = if (random 1 >= 0.85) then { _woundTypes select _highestPossibleSpot @@ -104,7 +105,7 @@ private _woundsCreated = []; // wound category (minor [0..0.5], medium[0.5..1.0], large[1.0+]) private _category = floor linearConversion [0, 1, _bleedingModifier, 0, 2, true]; - private _classComplex = _woundClassIDToAdd + 0.1 * _category; + private _classComplex = 10 * _woundClassIDToAdd + _category; // Create a new injury. Format [0:classComplex, 1:bodypart, 2:amountOf, 3:bleedingRate, 4:woundDamage] private _injury = [_classComplex, _bodyPartNToAdd, 1, _bleeding, _woundDamage]; @@ -112,9 +113,10 @@ private _woundsCreated = []; if (_bodyPartNToAdd == 0 || {_bodyPartNToAdd == 1 && {_woundDamage > PENETRATION_THRESHOLD}}) then { _critialDamage = true; }; -#ifdef DEBUG_MODE_FULL + + #ifdef DEBUG_MODE_FULL systemChat format["%1, damage: %2, peneration: %3, bleeding: %4, pain: %5", _bodyPart, _woundDamage toFixed 2, _woundDamage > PENETRATION_THRESHOLD, _bleeding toFixed 3, _pain toFixed 3]; -#endif + #endif // Emulate damage to vital organs switch (true) do { @@ -131,11 +133,17 @@ private _woundsCreated = []; [QEGVAR(medical,FatalInjury), _unit] call CBA_fnc_localEvent; }; }; - }; - - // todo `forceWalk` based on leg damage - if (_causeLimping == 1 && {_woundDamage > LIMPING_DAMAGE_THRESHOLD} && {_bodyPartNToAdd > 3}) then { - [_unit, true] call EFUNC(medical_engine,setLimping); + case (_causeFracture && {EGVAR(medical,fractures) > 0} && {_bodyPartNToAdd > 3} && {_woundDamage > FRACTURE_DAMAGE_THRESHOLD}): { // ToDo: Arm fractures? + TRACE_1("fracture",_bodyPartNToAdd); + // todo: play sound? + private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]; + _fractures set [_bodyPartNToAdd, 1]; + _unit setVariable [QEGVAR(medical,fractures), _fractures, true]; + _updateLimping = true; + }; + case (_causeLimping && {EGVAR(medical,limping) > 0} && {_bodyPartNToAdd > 3} && {_woundDamage > LIMPING_DAMAGE_THRESHOLD}): { + _updateLimping = true; + }; }; // if possible merge into existing wounds @@ -145,9 +153,10 @@ private _woundsCreated = []; if ( (_classComplex == _classID) && {_bodyPartNToAdd == _bodyPartN} && - {(_bodyPartNToAdd != 1) || {(_woundDamage < PENETRATION_THRESHOLD) isEqualTo (_oldDamage < PENETRATION_THRESHOLD)}} // penetrating body damage is handled differently + {(_bodyPartNToAdd != 1) || {(_woundDamage < PENETRATION_THRESHOLD) isEqualTo (_oldDamage < PENETRATION_THRESHOLD)}} && // penetrating body damage is handled differently + {(_bodyPartNToAdd > 3) || {!_causeLimping} || {(_woundDamage <= LIMPING_DAMAGE_THRESHOLD) isEqualTo (_oldDamage <= LIMPING_DAMAGE_THRESHOLD)}} // ensure limping damage is stacked correctly ) exitWith { - TRACE_2("merging with existing wound",_forEachIndex,_x); + TRACE_2("merging with existing wound",_injury,_x); private _newAmountOf = _oldAmountOf + 1; _x set [2, _newAmountOf]; private _newBleeding = (_oldAmountOf * _oldBleeding + _bleeding) / _newAmountOf; @@ -162,13 +171,14 @@ private _woundsCreated = []; TRACE_1("adding new wound",_injury); _openWounds pushBack _injury; }; - - // Store the injury so we can process it later correctly. - _woundsCreated pushBack _injury; }; }; } forEach _thresholds; +if (_updateLimping) then { + [_unit] call EFUNC(medical_engine,setLimping); +}; + _unit setVariable [QEGVAR(medical,openWounds), _openWounds, true]; _unit setVariable [QEGVAR(medical,bodyPartDamage), _bodyPartDamage, true]; @@ -182,4 +192,4 @@ if (_critialDamage || {_painLevel > PAIN_UNCONSCIOUS}) then { [_unit] call FUNC(handleIncapacitation); }; -TRACE_5("exit",_unit,_painLevel,GET_PAIN(_unit),_unit getVariable QEGVAR(medical,openWounds),_woundsCreated); +TRACE_4("exit",_unit,_painLevel,GET_PAIN(_unit),_unit getVariable QEGVAR(medical,openWounds)); diff --git a/addons/medical_engine/functions/fnc_setLimping.sqf b/addons/medical_engine/functions/fnc_setLimping.sqf index 11ead53c54..6cb7c067d7 100644 --- a/addons/medical_engine/functions/fnc_setLimping.sqf +++ b/addons/medical_engine/functions/fnc_setLimping.sqf @@ -11,17 +11,47 @@ * None * * Example: - * [player, true] call ace_medical_engine_fnc_setLimping + * [player] call ace_medical_engine_fnc_setLimping * * Public: No */ -params [["_unit", objNull, [objNull]], ["_isLimping", true, [false]]]; +params [["_unit", objNull, [objNull]]]; -if (!local _unit) exitWith { - ERROR("Unit not local or null"); +if (!local _unit) exitWith { ERROR("Unit not local or null"); }; + +private _isLimping = false; + +if (EGVAR(medical,fractures) > 0) then { + private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]; + if (((_fractures select 4) == 1) || {(_fractures select 5) == 1}) then { + TRACE_1("limping because of fracture",_fractures); + _isLimping = true; + }; + + if (EGVAR(medical,fractures) == 2) then { // block sprinting if we have a leg splint on + private _isSprintBlocked = ((_fractures select 4) == -1) || {(_fractures select 5) == -1}; + TRACE_2("",_isSprintBlocked,_fractures); + if (_isSprintBlocked || {!isSprintAllowed _unit}) then { // only update status effect if we need to + [_unit, "blockSprint", QEGVAR(medical,fracture), _isSprintBlocked] call EFUNC(common,statusEffect_set); + }; + }; }; +if (!_isLimping && {EGVAR(medical,limping) > 0}) then { + private _woundsToCheck = _unit getVariable [QEGVAR(medical,openWounds), []]; + if (EGVAR(medical,limping) == 2) then { + _woundsToCheck = _woundsToCheck + (_unit getVariable [QEGVAR(medical,bandagedWounds), []]); // append will break things + }; + { + _x params ["_xClassID", "_xBodyPartN", "_xAmountOf", "", "_xDamage"]; + if ((_xBodyPartN > 3) && {_xAmountOf > 0} && {_xDamage > LIMPING_DAMAGE_THRESHOLD} && { + (EGVAR(medical_damage,woundsData) select (_xClassID / 10)) select 7}) exitWith { // select _causeLimping from woundsData + TRACE_1("limping because of wound",_x); + _isLimping = true; + }; + } forEach _woundsToCheck; +}; _unit setVariable [QEGVAR(medical,isLimping), _isLimping, true]; // refresh diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index f64351b027..ef55cb2375 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -1,6 +1,6 @@ -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define ENABLE_PERFORMANCE_COUNTERS +#define DEBUG_MODE_FULL +#define DISABLE_COMPILE_CACHE +#define ENABLE_PERFORMANCE_COUNTERS #define ALL_BODY_PARTS ["head", "body", "leftarm", "rightarm", "leftleg", "rightleg"] @@ -74,6 +74,9 @@ // Minimum leg damage required for limping #define LIMPING_DAMAGE_THRESHOLD 0.30 +// Minimum limb damage required for fracture +#define FRACTURE_DAMAGE_THRESHOLD 0.50 + // Minimum body part damage required for blood effect on uniform #define VISUAL_BODY_DAMAGE_THRESHOLD 0.35 diff --git a/addons/medical_gui/data/body_image/leg_left_bonel.paa b/addons/medical_gui/data/body_image/leg_left_bonel.paa new file mode 100644 index 0000000000..f878074995 Binary files /dev/null and b/addons/medical_gui/data/body_image/leg_left_bonel.paa differ diff --git a/addons/medical_gui/data/body_image/leg_right_boner.paa b/addons/medical_gui/data/body_image/leg_right_boner.paa new file mode 100644 index 0000000000..3b0dc02605 Binary files /dev/null and b/addons/medical_gui/data/body_image/leg_right_boner.paa differ diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index 3506bfd01f..b6f82f9c30 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -20,6 +20,7 @@ params ["_ctrlGroup", "_target"]; // Get tourniquets, damage, and blood loss for target private _tourniquets = GET_TOURNIQUETS(_target); +private _fractures = _target getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]; private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0, 0, 0, 0, 0, 0]]; private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; @@ -29,7 +30,7 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; } forEach (_target getVariable [QEGVAR(medical,openWounds), []]); { - _x params ["_bodyPartIDC", ["_tourniquetIDC", -1]]; + _x params ["_bodyPartIDC", ["_tourniquetIDC", -1], ["_fractureIDC", -1]]; // Show or hide the tourniquet icon if (_tourniquetIDC != -1) then { @@ -37,6 +38,21 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; private _ctrlTourniquet = _ctrlGroup controlsGroupCtrl _tourniquetIDC; _ctrlTourniquet ctrlShow _hasTourniquet; }; + // Show or hide fractrue/bones + if (_fractureIDC != -1) then { + private _ctrlBone = _ctrlGroup controlsGroupCtrl _fractureIDC; + switch (_fractures select _forEachIndex) do { + case (0): {_ctrlBone ctrlShow false;}; + case (1): { + _ctrlBone ctrlShow true; + _ctrlBone ctrlSetTextColor [1, 0, 0, 1]; + }; + case (-1): { + _ctrlBone ctrlShow true; + _ctrlBone ctrlSetTextColor [0, 0, 1, 1]; + }; + }; + }; // Update body part color based on blood loss and damage private _bloodLoss = _bodyPartBloodLoss select _forEachIndex; @@ -54,6 +70,6 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; [IDC_BODY_TORSO], [IDC_BODY_ARMLEFT, IDC_BODY_ARMLEFT_T], [IDC_BODY_ARMRIGHT, IDC_BODY_ARMRIGHT_T], - [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_T], - [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_T] + [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B], + [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_T, IDC_BODY_LEGRIGHT_B] ]; diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 04ce75d22f..1876e30c68 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -58,6 +58,10 @@ switch (GET_HEMORRHAGE(_target)) do { if (HAS_TOURNIQUET_APPLIED_ON(_target,_selectionN)) then { _entries pushBack [localize LSTRING(Status_Tourniquet_Applied), [0.77, 0.51, 0.08, 1]]; }; +switch ((_target getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]) select _selectionN) do { + case (1): {_entries pushBack ["fracture!", [1, 0, 0, 1]];}; + case (-1): {_entries pushBack ["splinted", [1, 1, 1, 1]];}; +}; // Indicate the amount of pain the unit is in if ([_target] call EFUNC(common,isAwake)) then { @@ -93,8 +97,8 @@ if (_totalIvVolume >= 1) then { private _woundEntries = []; private _fnc_getWoundDescription = { - private _classIndex = floor _woundClassID; - private _category = round (10 * (_woundClassID % 1)); + private _classIndex = _woundClassID / 10; + private _category = _woundClassID % 10; private _className = EGVAR(medical_damage,woundsData) select _classIndex select 6; private _suffix = ["Minor", "Medium", "Large"] select _category; private _woundName = localize format [ELSTRING(medical_damage,%1_%2), _className, _suffix]; diff --git a/addons/medical_gui/gui.hpp b/addons/medical_gui/gui.hpp index eceb263a60..379d86195b 100644 --- a/addons/medical_gui/gui.hpp +++ b/addons/medical_gui/gui.hpp @@ -55,6 +55,14 @@ class GVAR(BodyImage): RscControlsGroupNoScrollbars { idc = IDC_BODY_ARMRIGHT_T; text = QPATHTOF(data\body_image\arm_right_t.paa); }; + class LegLeftB: ArmLeftT { + idc = IDC_BODY_LEGLEFT_B; + text = QPATHTOF(data\body_image\leg_left_bonel.paa); + }; + class LegRightB: ArmLeftT { + idc = IDC_BODY_LEGRIGHT_B; + text = QPATHTOF(data\body_image\leg_right_boner.paa); + }; class LegLeftT: ArmLeftT { idc = IDC_BODY_LEGLEFT_T; text = QPATHTOF(data\body_image\leg_left_t.paa); @@ -557,6 +565,14 @@ class RscTitles { w = POS_W(8.5); h = POS_H(8.5); }; + class LegLeftB: LegLeftB { + w = POS_W(8.5); + h = POS_H(8.5); + }; + class LegRightB: LegRightB { + w = POS_W(8.5); + h = POS_H(8.5); + }; class LegLeftT: LegLeftT { w = POS_W(8.5); h = POS_H(8.5); diff --git a/addons/medical_gui/script_component.hpp b/addons/medical_gui/script_component.hpp index a1c8fb6a8d..30674ad69f 100644 --- a/addons/medical_gui/script_component.hpp +++ b/addons/medical_gui/script_component.hpp @@ -67,6 +67,8 @@ #define IDC_BODY_ARMRIGHT_T 6040 #define IDC_BODY_LEGLEFT_T 6045 #define IDC_BODY_LEGRIGHT_T 6050 +#define IDC_BODY_LEGRIGHT_B 6055 +#define IDC_BODY_LEGLEFT_B 6060 #define IDC_TRIAGE_STATUS 7000 #define IDC_TRIAGE_SELECT 7100 diff --git a/addons/medical_gui/ui/splint.paa b/addons/medical_gui/ui/splint.paa new file mode 100644 index 0000000000..521809124a Binary files /dev/null and b/addons/medical_gui/ui/splint.paa differ diff --git a/addons/medical_status/functions/fnc_initUnit.sqf b/addons/medical_status/functions/fnc_initUnit.sqf index d53cedbc63..078bcafeef 100644 --- a/addons/medical_status/functions/fnc_initUnit.sqf +++ b/addons/medical_status/functions/fnc_initUnit.sqf @@ -50,9 +50,6 @@ _unit setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true]; _unit setVariable [QEGVAR(medical,occludedMedications), nil, true]; //Delayed Medications (from tourniquets) _unit setVariable [QEGVAR(medical,ivBags), nil, true]; -// - Update wound bleeding -[_unit] call EFUNC(medical_status,updateWoundBloodLoss); - // triage card and logs _unit setVariable [QEGVAR(medical,triageLevel), 0, true]; _unit setVariable [QEGVAR(medical,triageCard), [], true]; diff --git a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp index ae1582c040..ef33268ed3 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp @@ -83,6 +83,19 @@ class GVAR(Actions) { callbackSuccess = QFUNC(treatmentTourniquetRemove); condition = QUOTE([ARR_2(_target,_bodyPart)] call FUNC(hasTourniquetAppliedTo)); }; + // --- splint + class Splint: BasicBandage { + displayName = "Splint"; // CSTRING(Apply_Tourniquet); + displayNameProgress = "Splinting"; // CSTRING(Applying_Tourniquet); + category = "bandage"; + icon = QPATHTOEF(medical_gui,ui\splint.paa); + allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"}; + items[] = {"ACE_splint"}; + treatmentTime = 7; + callbackSuccess = QFUNC(splint); + condition = QUOTE(call FUNC(splintCondition)); + litter[] = {}; + }; // --- syringes class Morphine: FieldDressing { diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index 17ed52fd4f..1b4cf41fdc 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -70,6 +70,18 @@ class CfgWeapons { mass = 2; }; }; + class ACE_splint: ACE_ItemCore { + scope = 2; + author = ECSTRING(common,ACETeam); + displayName = "splint"; + picture = QPATHTOF(ui\items\tourniquet_x_ca.paa); + model = QPATHTOF(data\tourniquet.p3d); + // descriptionShort = CSTRING(Tourniquet_Desc_Short); + // descriptionUse = CSTRING(Tourniquet_Desc_Use); + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 2; + }; + }; class ACE_morphine: ACE_ItemCore { scope = 2; author = ECSTRING(common,ACETeam); diff --git a/addons/medical_treatment/XEH_PREP.hpp b/addons/medical_treatment/XEH_PREP.hpp index 77e91fbc2a..5d0e71ae53 100644 --- a/addons/medical_treatment/XEH_PREP.hpp +++ b/addons/medical_treatment/XEH_PREP.hpp @@ -36,6 +36,10 @@ PREP(treatmentTourniquet); PREP(treatmentTourniquetLocal); PREP(treatmentTourniquetRemove); +PREP(splint); +PREP(splintCondition); +PREP(splintLocal); + // misc PREP(addToLog); PREP(addToTriageCard); diff --git a/addons/medical_treatment/XEH_postInit.sqf b/addons/medical_treatment/XEH_postInit.sqf index ecaca5cea6..77b99aa6fb 100644 --- a/addons/medical_treatment/XEH_postInit.sqf +++ b/addons/medical_treatment/XEH_postInit.sqf @@ -17,6 +17,8 @@ if (isServer) then { [QGVAR(treatmentCPRLocal), FUNC(treatmentCPRLocal)] call CBA_fnc_addEventHandler; [QGVAR(treatmentFullHealLocal), FUNC(treatmentFullHealLocal)] call CBA_fnc_addEventHandler; +[QGVAR(treatmentSplintLocal), FUNC(splintLocal)] call CBA_fnc_addEventHandler; + // action events [QGVAR(actionCheckPulseLocal), FUNC(actionCheckPulseLocal)] call CBA_fnc_addEventHandler; [QGVAR(actionCheckBloodPressureLocal), FUNC(actionCheckBloodPressureLocal)] call CBA_fnc_addEventHandler; diff --git a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf index e824d27e76..7622106054 100644 --- a/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf +++ b/addons/medical_treatment/functions/fnc_findMostEffectiveWound.sqf @@ -39,16 +39,12 @@ private _effectivenessFound = -1; { _x params ["_classID", "_partIndexN", "_amountOf", "_bleeding", "_damage"]; - private _classIndex = floor _classID; - private _category = round (10 * (_classID % 1)); - // Ignore wounds on other bodyparts if (_partIndexN == _partIndex) then { private _woundEffectiveness = _effectiveness; // Select the classname from the wound classname storage - private _suffix = ["Minor", "Medium", "Large"] select _category; - private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classIndex, _suffix]; + private _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; // Get the effectiveness of the bandage on this wound type if (isClass (_config >> _className)) then { diff --git a/addons/medical_treatment/functions/fnc_getBandageTime.sqf b/addons/medical_treatment/functions/fnc_getBandageTime.sqf index ff11697dfb..48fd27fdac 100644 --- a/addons/medical_treatment/functions/fnc_getBandageTime.sqf +++ b/addons/medical_treatment/functions/fnc_getBandageTime.sqf @@ -28,7 +28,7 @@ TRACE_3("findMostEffectiveWound",_wound,_woundIndex,_effectiveness); if (_wound isEqualTo EMPTY_WOUND) exitWith { 0 }; _wound params ["_classID", "", "_amountOf", "_bloodloss", "_damage"]; -private _category = round (10 * (_classID % 1)); +private _category = (_classID % 10); // Base bandage time is based on wound size and remaining percentage private _bandageTime = ([ diff --git a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf index 76290f9b82..2c87b23949 100644 --- a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf @@ -21,12 +21,8 @@ params ["_target", "_impact", "_part", "_injuryIndex", "_injury", "_bandage"]; TRACE_6("handleBandageOpening",_target,_impact,_part,_injuryIndex,_injury,_bandage); _injury params ["_classID", "_bodyPartN"]; -private _classIndex = floor _classID; -private _category = round (10 * (_classID % 1)); - -private _postfix = ["Minor", "Medium", "Large"] select _category; -private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classIndex, _postfix]; +private _className = EGVAR(medical_damage,woundClassNamesComplex) select _classID; private _reopeningChance = DEFAULT_BANDAGE_REOPENING_CHANCE; private _reopeningMinDelay = DEFAULT_BANDAGE_REOPENING_MIN_DELAY; private _reopeningMaxDelay = DEFAULT_BANDAGE_REOPENING_MAX_DELAY; @@ -121,6 +117,11 @@ if (random 1 <= _reopeningChance) then { _target setVariable [QEGVAR(medical,openWounds), _openWounds, true]; [_target] call EFUNC(medical_status,updateWoundBloodLoss); + + // Check if we gained limping from this wound re-opening + if ((EGVAR(medical,limping) == 1) && {_bodyPartN > 3}) then { + [_target] call EFUNC(medical_engine,setLimping); + }; }; } else { TRACE_3("no match",_selectedInjury,_classID,_bodyPartN); diff --git a/addons/medical_treatment/functions/fnc_splint.sqf b/addons/medical_treatment/functions/fnc_splint.sqf new file mode 100644 index 0000000000..4ced63109c --- /dev/null +++ b/addons/medical_treatment/functions/fnc_splint.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Apply a splint to the patient + * + * Arguments: + * 0: The medic + * 1: The patient + * 2: Body part + * + * Return Value: + * Nothing + * + * Example: + * [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_splint + * + * Public: No + */ + +params ["_caller", "_target", "_bodyPart"]; +TRACE_3("splint",_caller,_target,_bodyPart); + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; + +[QGVAR(treatmentSplintLocal), [_caller, _target, _partIndex], _target] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_splintCondition.sqf b/addons/medical_treatment/functions/fnc_splintCondition.sqf new file mode 100644 index 0000000000..3978518529 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_splintCondition.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Can apply a splint to the patient + * + * Arguments: + * 0: The medic + * 1: The patient + * 2: Body part + * + * Return Value: + * Nothing + * + * Example: + * [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_splintCondition + * + * Public: No + */ + +params ["", "_target", "_bodyPart"]; + +private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]; + +(_fractures select _partIndex) == 1 diff --git a/addons/medical_treatment/functions/fnc_splintLocal.sqf b/addons/medical_treatment/functions/fnc_splintLocal.sqf new file mode 100644 index 0000000000..003adc073c --- /dev/null +++ b/addons/medical_treatment/functions/fnc_splintLocal.sqf @@ -0,0 +1,31 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Apply a splint to the patient + * + * Arguments: + * 0: The medic + * 1: The patient + * 2: Body part index + * + * Return Value: + * Nothing + * + * Example: + * [player, cursorObject, 4] call ace_medical_treatment_fnc_splintLocal + * + * Public: No + */ + +params ["_caller", "_target", "_bodyPartNum"]; +TRACE_3("splintLocal",_caller,_target,_bodyPart); + +// Place a tourniquet on the bodypart +private _fractures = _target getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]; +_fractures set [_bodyPartNum, -1]; +_target setVariable [QEGVAR(medical,fractures), _fractures, true]; + +// Check if we fixed limping from this treatment +[_target] call EFUNC(medical_engine,setLimping); + +// toDo: AddToLog: diff --git a/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf index 3328150938..9b362954bd 100644 --- a/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentBandageLocal.sqf @@ -33,7 +33,8 @@ if (_effectiveness == -1) exitWith {}; // Find the impact this bandage has and reduce the amount this injury is present private _amountOf = _wound select 2; private _impact = _effectiveness min _amountOf; -_wound set [2, _amountOf - _impact]; +_amountOf = _amountOf - _impact; +_wound set [2, _amountOf]; _openWounds set [_woundIndex, _wound]; _target setVariable [QEGVAR(medical,openWounds), _openWounds, true]; @@ -45,4 +46,9 @@ if (_impact > 0 && {GVAR(advancedBandages) && {GVAR(woundReopening)}}) then { [_target, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening); }; +// Check if we fixed limping from this treatment +if ((EGVAR(medical,limping) == 1) && {_amountOf <= 0} && {_target getVariable [QEGVAR(medical,isLimping), false]}) then { + [_target] call EFUNC(medical_engine,setLimping); +}; + true diff --git a/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf index dfc712872b..7369eb57aa 100644 --- a/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentFullHealLocal.sqf @@ -39,6 +39,7 @@ _target setVariable [QEGVAR(medical,openWounds), [], true]; _target setVariable [QEGVAR(medical,bandagedWounds), [], true]; _target setVariable [QEGVAR(medical,stitchedWounds), [], true]; _target setVariable [QEGVAR(medical,isLimping), false, true]; +_target setVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0], true]; // - Update wound bleeding [_target] call EFUNC(medical_status,updateWoundBloodLoss); @@ -70,7 +71,7 @@ _target setVariable [VAR_MEDICATIONS, [], true]; // Reset triage card since medication is all reset _target setVariable [QEGVAR(medical,triageCard), [], true]; -[_target, false] call EFUNC(medical_engine,setLimping); +[_target] call EFUNC(medical_engine,setLimping); // Resetting damage _target setDamage 0; diff --git a/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf b/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf index ab9906cc34..a49560ac01 100644 --- a/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentSurgicalKit_onProgress.sqf @@ -35,6 +35,13 @@ if (_totalTime - _elapsedTime <= (count _bandagedWounds - 1) * 5) then { _target setVariable [QEGVAR(medical,bandagedWounds), _bandagedWounds, true]; _target setVariable [QEGVAR(medical,stitchedWounds), _stitchedWounds, true]; TRACE_3("stitched",_treatedWound,count _bandagedWounds,count _stitchedWounds); + + // Check if we fixed limping from this treatment + if ((EGVAR(medical,limping) == 2) && {_target getVariable [QEGVAR(medical,isLimping), false]}) then { + _treatedWound params ["", "_partN"]; + if (_partN < 4) exitWith {}; + [_target] call EFUNC(medical_engine,setLimping); + }; }; true