From a71879ccea4638c63f874bb89754fdcb51744f16 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Tue, 8 Oct 2019 10:44:49 -0500 Subject: [PATCH] Medical - Increase severity of falling damage and Improve non-selectionSpecific wounds (#7214) * Medical - Increase severity of falling damage * Improve non-selectionSpecific wounds * Use macros for hitpoint indexes --- .../medical_damage/ACE_Medical_Injuries.hpp | 9 +++-- addons/medical_damage/XEH_preInit.sqf | 4 +-- .../functions/fnc_parseConfigForInjuries.sqf | 4 +++ .../functions/fnc_woundsHandlerSQF.sqf | 13 +++---- .../functions/fnc_handleDamage.sqf | 36 +++++++++++++------ .../medical_engine/script_macros_medical.hpp | 7 ++++ 6 files changed, 50 insertions(+), 23 deletions(-) diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index 4dfc066993..fd03981398 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -47,7 +47,6 @@ class ACE_Medical_Injuries { }; // Also called tears, these are separating wounds that produce ragged edges. They are produced by a tremendous force against the body, either from an internal source as in childbirth, or from an external source like a punch. class Laceration { - selections[] = {"All"}; causes[] = {"vehiclecrash", "collision", "punch"}; bleeding = 0.05; pain = 0.2; @@ -94,11 +93,11 @@ class ACE_Medical_Injuries { selectionSpecific = 0; }; class vehiclecrash { - thresholds[] = {{0.5, 5}, {0.3, 2}, {0.05, 1}}; + thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; }; class collision { - thresholds[] = {{0.5, 5}, {0.3, 2}, {0.05, 1}}; + thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; }; class backblast { @@ -114,8 +113,8 @@ class ACE_Medical_Injuries { selectionSpecific = 1; }; class falling { - thresholds[] = {{0.6, 4}, {0.35, 2}, {0.1, 1}}; - selectionSpecific = 1; + thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered + selectionSpecific = 0; }; class ropeburn { thresholds[] = {{0.1, 1}}; diff --git a/addons/medical_damage/XEH_preInit.sqf b/addons/medical_damage/XEH_preInit.sqf index 081b0cf48b..d537236aeb 100644 --- a/addons/medical_damage/XEH_preInit.sqf +++ b/addons/medical_damage/XEH_preInit.sqf @@ -26,10 +26,10 @@ addMissionEventHandler ["Loaded",{ // }; [QEGVAR(medical,woundReceived), { - params ["_unit", "_woundedHitPoint", "_receivedDamage", "", "_ammo"]; + params ["_unit", "_woundedHitPoint", "_receivedDamage", "", "_ammo", "_damageSelectionArray"]; private _typeOfDamage = _ammo call FUNC(getTypeOfDamage); - [_unit, _woundedHitPoint, _receivedDamage, _typeOfDamage] call FUNC(woundsHandlerActive); + [_unit, _woundedHitPoint, _receivedDamage, _typeOfDamage, _damageSelectionArray] call FUNC(woundsHandlerActive); }] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index 89da4bca4e..848c78c893 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -76,6 +76,7 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS GVAR(allDamageTypesData) setVariable [_className, [_thresholds, _selectionSpecific > 0, _woundTypes]]; + /* // extension loading private _minDamageThresholds = (_thresholds apply {str (_x select 0)}) joinString ":"; private _amountThresholds = (_thresholds apply {str (_x select 1)}) joinString ":"; @@ -93,8 +94,10 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS // private _extensionRes = "ace_medical" callExtension _extensionArgs; // TRACE_1("",_extensionRes); + */ } forEach configProperties [_damageTypesConfig, "isClass _x"]; +/* // extension loading { _x params ["_classID", "_selections", "_bleedingRate", "_pain", "_damageExtrema", "_causes", "_displayName"]; @@ -128,3 +131,4 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS } forEach GVAR(woundsData); // "ace_medical" callExtension "ConfigComplete"; +*/ diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf index f7ec2dd540..969dc257fd 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf @@ -8,18 +8,19 @@ * 1: Name Of Body Part * 2: Amount Of Damage * 3: Type of the damage done + * 4: Weighted array of damaged selections * * Return Value: * None * * Example: - * [player, "Body", 0.5, "bullet"] call ace_medical_damage_fnc_woundsHandlerSQF + * [player, "Body", 0.5, "bullet", [1, 1]] call ace_medical_damage_fnc_woundsHandlerSQF * * Public: No */ -params ["_unit", "_bodyPart", "_damage", "_typeOfDamage"]; -TRACE_4("woundsHandlerSQF",_unit,_bodyPart,_damage,_typeOfDamage); +params ["_unit", "_bodyPart", "_damage", "_typeOfDamage", "_damageSelectionArray"]; +TRACE_5("woundsHandlerSQF",_unit,_bodyPart,_damage,_typeOfDamage,_damageSelectionArray); // Convert the selectionName to a number and ensure it is a valid selection. private _bodyPartN = ALL_BODY_PARTS find toLower _bodyPart; @@ -47,7 +48,7 @@ private _allPossibleInjuries = []; // Check if the damage is higher as the min damage for the specific injury if (_damage >= _minDamage && {_damage <= _maxDamage || _maxDamage < 0}) then { // Check if the injury can be applied to the given selection name - if ("All" in _selections || {_bodyPart in _selections}) then { // @todo, this is case sensitive! + // if ("All" in _selections || {_bodyPart in _selections}) then { // @todo, this is case sensitive! [we have no injuries that use this, disabled for now] // Find the wound which has the highest minimal damage, so we can use this later on for adding the correct injuries if (_minDamage > _highestPossibleDamage) then { @@ -57,7 +58,7 @@ private _allPossibleInjuries = []; // Store the valid possible injury for the damage type, damage amount and selection _allPossibleInjuries pushBack _x; - }; + // }; }; } forEach _woundTypes; @@ -87,7 +88,7 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra _oldInjury params ["_woundClassIDToAdd", "", "_injuryBleedingRate", "_injuryPain", "", "", "", "_causeLimping", "_causeFracture"]; - private _bodyPartNToAdd = [floor random 6, _bodyPartN] select _isSelectionSpecific; // 6 == count ALL_BODY_PARTS + private _bodyPartNToAdd = if (_isSelectionSpecific) then {_bodyPartN} else {selectRandomWeighted _damageSelectionArray}; _bodyPartDamage set [_bodyPartNToAdd, (_bodyPartDamage select _bodyPartNToAdd) + _woundDamage]; _bodyPartVisParams set [[1,2,3,3,4,4] select _bodyPartNToAdd, true]; // Mark the body part index needs updating diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index d810960f4d..000c90b911 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -80,6 +80,12 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { ]; TRACE_2("incoming",_allDamages,_damageStructural); + // represents all incoming damage for selecting a non-selectionSpecific wound location, (used for selectRandomWeighted [value1,weight1,value2....]) + private _damageSelectionArray = [ + HITPOINT_INDEX_HEAD, _damageHead, HITPOINT_INDEX_BODY, _damageBody, HITPOINT_INDEX_LARM, _damageLeftArm, + HITPOINT_INDEX_RARM, _damageRightArm, HITPOINT_INDEX_LLEG, _damageLeftLeg, HITPOINT_INDEX_RLEG, _damageRightLeg + ]; + _allDamages sort false; (_allDamages select 0) params ["_receivedDamage", "", "_woundedHitPoint"]; if (_damageHead >= HEAD_DAMAGE_THRESHOLD) then { @@ -92,6 +98,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { if (_receivedDamage == 0) then { _receivedDamage = _damageStructural; _woundedHitPoint = "Body"; + _damageSelectionArray = [1, 1]; // sum of weights would be 0 }; // Environmental damage sources all have empty ammo string @@ -100,7 +107,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { - _ammo = "#collision"; + _ammo = "#collision"; // non-selectionSpecific so only _damageSelectionArray matters /* If shooter != unit then they hit unit, otherwise it could be: @@ -110,10 +117,11 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { Assume fall damage for downward velocity because it's most common */ if (_shooter == _unit && {(velocity _unit select 2) < -2}) then { - _woundedHitPoint = selectRandom ["RightLeg", "LeftLeg"]; + _ammo = "#falling"; // non-selectionSpecific so only _damageSelectionArray matters + _damageSelectionArray = [4, 1, 5, 1]; // selectRandom ["RightLeg", "LeftLeg"]; TRACE_5("Fall",_unit,_shooter,_instigator,_damage,_receivedDamage); } else { - _woundedHitPoint = selectRandom ["RightArm", "LeftArm", "RightLeg", "LeftLeg"]; + _damageSelectionArray = [2, 1, 3, 1, 4, 1, 5, 1]; // selectRandom ["RightArm", "LeftArm", "RightLeg", "LeftLeg"]; TRACE_5("Collision",_unit,_shooter,_instigator,_damage,_receivedDamage); }; @@ -122,12 +130,16 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Higher momentum results in higher chance for head to be hit for more lethality if (_receivedDamage > 0.35) then { private _headHitWeight = (_receivedDamage / 2) min 1; - _woundedHitPoint = selectRandomWeighted ["Body", (1 - _headHitWeight), "Head", _headHitWeight]; + if (_recievedDamage < 0.6) then { + _damageSelectionArray append [0, (1 - _headHitWeight), 1, _headHitWeight]; + } else { + _damageSelectionArray = [0, (1 - _headHitWeight), 1, _headHitWeight]; + } }; } else { // Anything else is almost guaranteed to be fire damage - _woundedHitPoint = selectRandom ["LeftLeg", "RightLeg", "Body"]; - _ammo = "#unknown"; + _damageSelectionArray = [1, 1, 4, 1, 5, 1]; // selectRandom ["Body", "LeftLeg", "RightLeg"]; + _ammo = "#unknown"; // non-selectionSpecific so only _damageSelectionArray matters // Fire damage can occur as lots of minor damage events // Combine these until significant enough to wound @@ -145,8 +157,8 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // No wounds for minor damage if (_receivedDamage > 1E-3) then { - [QEGVAR(medical,woundReceived), [_unit, _woundedHitPoint, _receivedDamage, _shooter, _ammo]] call CBA_fnc_localEvent; - TRACE_2("received",_receivedDamage,_woundedHitPoint); + TRACE_3("received",_receivedDamage,_woundedHitPoint,_damageSelectionArray); + [QEGVAR(medical,woundReceived), [_unit, _woundedHitPoint, _receivedDamage, _shooter, _ammo, _damageSelectionArray]] call CBA_fnc_localEvent; }; // Clear stored damages otherwise they will influence future damage events @@ -169,7 +181,7 @@ if ( {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning"]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning", [HITPOINT_INDEX_BODY, 1]]] call CBA_fnc_localEvent; TRACE_5("Drowning",_unit,_shooter,_instigator,_damage,_newDamage); 0 @@ -185,7 +197,11 @@ if ( {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#vehiclecrash"]] call CBA_fnc_localEvent; + private _damageSelectionArray = [ + HITPOINT_INDEX_HEAD, 1, HITPOINT_INDEX_BODY, 1, HITPOINT_INDEX_LARM, 1, + HITPOINT_INDEX_RARM, 1, HITPOINT_INDEX_LLEG, 1, HITPOINT_INDEX_RLEG, 1 + ]; + [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#vehiclecrash", _damageSelectionArray]] call CBA_fnc_localEvent; TRACE_5("Crash",_unit,_shooter,_instigator,_damage,_newDamage); 0 diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index 103a28cbec..7f50866f0e 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -6,6 +6,13 @@ #define ALL_SELECTIONS ["head", "body", "hand_l", "hand_r", "leg_l", "leg_r"] #define ALL_HITPOINTS ["HitHead", "HitBody", "HitLeftArm", "HitRightArm", "HitLeftLeg", "HitRightLeg"] +#define HITPOINT_INDEX_HEAD 0 +#define HITPOINT_INDEX_BODY 1 +#define HITPOINT_INDEX_LARM 2 +#define HITPOINT_INDEX_RARM 3 +#define HITPOINT_INDEX_LLEG 4 +#define HITPOINT_INDEX_RLEG 5 + // Damage threshold above which fatal organ damage can occur #define HEAD_DAMAGE_THRESHOLD 1 #define ORGAN_DAMAGE_THRESHOLD 0.6