From 816d5343045100fc06dbd6681373c068d1a29720 Mon Sep 17 00:00:00 2001 From: James Woods Date: Sun, 20 Feb 2022 14:07:35 +0000 Subject: [PATCH 01/30] Add vehicle explosion handling --- .../functions/fnc_handleDamage.sqf | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 1b3bb238a11..afc12585059 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -67,6 +67,34 @@ if ( 0 }; +// Being inside an exploding vehicle doesn't trigger for each hitpoint +// It seems to fire twice with ammo type "FuelExplosion" or "FuelExplosionBig" +if ( + _hitPoint isEqualTo "#structural" && + {_ammo isKindOf "FuelExplosion"} && + {_vehicle != _unit} && + {_damage == 1} +) exitwith { + // triggers twice, so do half damage each time. not very important as it's basically always lethal + private _hit = GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "indirectHit", 10)/2; + private _uniform = uniform _unit; + if (_uniform isEqualTo "") then { + _uniform = getText (configOf _unit >> "nakedUniform"); + }; + private _uniformClass = GET_STRING(configFile >> "CfgWeapons" >> _uniform >> "ItemInfo" >> "uniformClass", "U_BasicBody"); + private _damages = []; + { + private _armor = [_unit, _x] call FUNC(getHitpointArmor); + // would be nice to move this into getHitpointArmor + private _shielding = GET_NUMBER(configFile >> "CfgVehicles" >> _uniformClass >> "Hitpoints" >> _x >> "explosionShielding", 1); + _damages pushBack [_hit*_shielding/_armor, ALL_BODY_PARTS select _forEachIndex, _hit*_shielding] + } forEach ALL_HITPOINTS; + TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); + [QEGVAR(medical,woundReceived), [_unit, _damages, _unit, _ammo]] call CBA_fnc_localEvent; + + 0 +}; + // This hitpoint is set to trigger last, evaluate all the stored damage values // to determine where wounds are applied if (_hitPoint isEqualTo "ace_hdbracket") exitWith { From 93bb7cd0dacb28d4e00a0e197a4a91c6cee2f122 Mon Sep 17 00:00:00 2001 From: James Woods Date: Fri, 10 Jun 2022 14:31:15 +0100 Subject: [PATCH 02/30] Missing semicolon --- addons/medical_engine/functions/fnc_handleDamage.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index afc12585059..68798d38dad 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -87,7 +87,7 @@ if ( private _armor = [_unit, _x] call FUNC(getHitpointArmor); // would be nice to move this into getHitpointArmor private _shielding = GET_NUMBER(configFile >> "CfgVehicles" >> _uniformClass >> "Hitpoints" >> _x >> "explosionShielding", 1); - _damages pushBack [_hit*_shielding/_armor, ALL_BODY_PARTS select _forEachIndex, _hit*_shielding] + _damages pushBack [_hit*_shielding/_armor, ALL_BODY_PARTS select _forEachIndex, _hit*_shielding]; } forEach ALL_HITPOINTS; TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); [QEGVAR(medical,woundReceived), [_unit, _damages, _unit, _ammo]] call CBA_fnc_localEvent; From 75f1cec1d92077b14b5e5c9e74019e76bccf5e4a Mon Sep 17 00:00:00 2001 From: Salluci Date: Tue, 13 Jun 2023 20:24:11 -0300 Subject: [PATCH 03/30] scale armor damage using passthrough --- .../functions/fnc_getItemArmor.sqf | 21 +++++++++++++------ .../functions/fnc_handleDamage.sqf | 11 ++++++---- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index 26e1bd693aa..b05e2c5b054 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" /* - * Author: Pterolatypus - * Returns the armor value the given item provides to a particular hitpoint, either from a cache or by reading the item config. + * Author: Pterolatypus, Salluci + * Returns the scaled armor value the given item provides to a particular hitpoint, either from a cache or by reading the item config. * * Arguments: * 0: Item Class * 1: Hitpoint * * Return Value: - * Item armor for the given hitpoint + * Scaled item armor for the given hitpoint * * Example: * ["V_PlateCarrier_rgr", "HitChest"] call ace_medical_engine_fnc_getItemArmor @@ -22,9 +22,10 @@ private _key = format ["%1$%2", _item, _hitpoint]; private _armor = GVAR(armorCache) get _key; if (isNil "_armor") then { + _armor = 0; + private _passThrough = 1; TRACE_2("Cache miss",_item,_hitpoint); if ("" in [_item, _hitpoint]) exitWith { - _armor = 0; GVAR(armorCache) set [_key, _armor]; }; @@ -38,14 +39,22 @@ if (isNil "_armor") then { } else { private _entry = _unitCfg >> "HitPoints" >> _hitpoint; _armor = getNumber (_unitCfg >> "armor") * (1 max getNumber (_entry >> "armor")); + _passThrough = (0.01 max getNumber (_entry >> "passThrough")); // prevent dividing by 0 }; } else { private _condition = format ["getText (_x >> 'hitpointName') == '%1'", _hitpoint]; private _entry = configProperties [_itemInfo >> "HitpointsProtectionInfo", _condition] param [0, configNull]; - - _armor = getNumber (_entry >> "armor"); + if (!isNull _entry) then { + _armor = getNumber (_entry >> "armor"); + _passThrough = (0.01 max getNumber (_entry >> "passThrough")); + }; }; + // Scale armor using passthrough to fix explosive resistant armor (#9063) + // Skip scaling for items that don't cover the hitpoint to prevent infinite armor + if (_armor != 0) then { + _armor = (log (_armor / _passThrough)) * 10; + }; GVAR(armorCache) set [_key, _armor]; }; diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 1b3bb238a11..be6e5104485 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -32,7 +32,8 @@ if (_hitPoint isEqualTo "") then { if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {_oldDamage}; private _newDamage = _damage - _oldDamage; -// Get armor value of hitpoint and calculate damage before armor +// Get scaled armor value of hitpoint and calculate damage before armor +// We scale using passThrough to handle explosive-resistant armor properly, fixing #9063 private _armor = [_unit, _hitpoint] call FUNC(getHitpointArmor); private _realDamage = _newDamage * _armor; TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); @@ -101,7 +102,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), [0,0]]; private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), [0,0]]; - // Find hit point that received the maxium damage + // Find hit point that received the maximum damage // Priority used for sorting if incoming damage is equal private _allDamages = [ [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, "Head"], @@ -115,8 +116,10 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { TRACE_2("incoming",_allDamages,_damageStructural); _allDamages sort false; - _allDamages = _allDamages apply {[_x select 2, _x select 3, _x select 0]}; - + + // We only need real damage at this point, divide by 10 to use engine range of 0-1 (or higher for really high damage) + _allDamages = _allDamages apply {[(_x select 0) / 10, _x select 3]}; + // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them if (_ammo isEqualTo "") then { From 386eda61e5d9488bc35d0fa8e30901651dd95345 Mon Sep 17 00:00:00 2001 From: GhostIsSpooky <69561145+Salluci@users.noreply.github.com> Date: Tue, 13 Jun 2023 22:52:19 -0300 Subject: [PATCH 04/30] add - to comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/medical_engine/functions/fnc_getItemArmor.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index b05e2c5b054..d62b80f7ccd 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -50,7 +50,7 @@ if (isNil "_armor") then { }; }; - // Scale armor using passthrough to fix explosive resistant armor (#9063) + // Scale armor using passthrough to fix explosive-resistant armor (#9063) // Skip scaling for items that don't cover the hitpoint to prevent infinite armor if (_armor != 0) then { _armor = (log (_armor / _passThrough)) * 10; From 510e6aa90ca91bc675a7b0af88a9c898b0fd0cb6 Mon Sep 17 00:00:00 2001 From: GhostIsSpooky <69561145+Salluci@users.noreply.github.com> Date: Tue, 13 Jun 2023 22:52:32 -0300 Subject: [PATCH 05/30] improve condition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/medical_engine/functions/fnc_getItemArmor.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index d62b80f7ccd..e3e8e5fc8ec 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -52,7 +52,7 @@ if (isNil "_armor") then { // Scale armor using passthrough to fix explosive-resistant armor (#9063) // Skip scaling for items that don't cover the hitpoint to prevent infinite armor - if (_armor != 0) then { + if (_armor isNotEqualTo 0) then { _armor = (log (_armor / _passThrough)) * 10; }; GVAR(armorCache) set [_key, _armor]; From f290e28f894e6a44eb8b3ba22eacb88a246fa3ee Mon Sep 17 00:00:00 2001 From: GhostIsSpooky <69561145+Salluci@users.noreply.github.com> Date: Tue, 13 Jun 2023 22:52:43 -0300 Subject: [PATCH 06/30] remove extra brackets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/medical_engine/functions/fnc_getItemArmor.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index e3e8e5fc8ec..27b431a1f27 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -46,7 +46,7 @@ if (isNil "_armor") then { private _entry = configProperties [_itemInfo >> "HitpointsProtectionInfo", _condition] param [0, configNull]; if (!isNull _entry) then { _armor = getNumber (_entry >> "armor"); - _passThrough = (0.01 max getNumber (_entry >> "passThrough")); + _passThrough = 0.01 max getNumber (_entry >> "passThrough"); }; }; From 9ad380dd172d342b5cfafbe1e7a201d8b7f588ff Mon Sep 17 00:00:00 2001 From: Salluci Date: Tue, 13 Jun 2023 22:53:42 -0300 Subject: [PATCH 07/30] remove extra brackets --- addons/medical_engine/functions/fnc_getItemArmor.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index 27b431a1f27..eb85849f916 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -39,7 +39,7 @@ if (isNil "_armor") then { } else { private _entry = _unitCfg >> "HitPoints" >> _hitpoint; _armor = getNumber (_unitCfg >> "armor") * (1 max getNumber (_entry >> "armor")); - _passThrough = (0.01 max getNumber (_entry >> "passThrough")); // prevent dividing by 0 + _passThrough = 0.01 max getNumber (_entry >> "passThrough"); // prevent dividing by 0 }; } else { private _condition = format ["getText (_x >> 'hitpointName') == '%1'", _hitpoint]; From 0c82347d5bdf13c2dadf8863f2cfe531824df5a7 Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 14 Jun 2023 01:22:12 -0300 Subject: [PATCH 08/30] fix damage sorting --- .../functions/fnc_getHitpointArmor.sqf | 14 +++--- .../functions/fnc_getItemArmor.sqf | 16 +++--- .../functions/fnc_handleDamage.sqf | 50 ++++++++++--------- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf index 62954a1b568..3e4c57e680d 100644 --- a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf +++ b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf @@ -8,7 +8,7 @@ * 1: Hitpoint * * Return Value: - * Total armor for the given hitpoint + * Total armor and scaled armor for the given hitpoint * * Example: * [player, "HitChest"] call ace_medical_engine_fnc_getHitpointArmor @@ -32,16 +32,18 @@ private _gear = [ private _rags = _gear joinString "$"; private _var = format [QGVAR(armorCache$%1), _hitpoint]; -_unit getVariable [_var, [""]] params ["_prevRags", "_armor"]; +_unit getVariable [_var, ["", 0, 0]] params ["_prevRags", "_armor", "_armorScaled"]; if (_rags != _prevRags) then { _armor = 0; - + _armorScaled = 0; { - _armor = _armor + ([_x, _hitpoint] call FUNC(getItemArmor)); + ([_x, _hitpoint] call FUNC(getItemArmor)) params ["_itemArmor", "_itemArmorScaled"]; + _armor = _armor + _itemArmor; + _armorScaled = _armorScaled + _itemArmorScaled; } forEach _gear; - _unit setVariable [_var, [_rags, _armor]]; + _unit setVariable [_var, [_rags, _armor, _armorScaled]]; }; -_armor // return +[_armor, _armorScaled] // return diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index eb85849f916..6094fbde1d9 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -19,14 +19,15 @@ params ["_item", "_hitpoint"]; private _key = format ["%1$%2", _item, _hitpoint]; -private _armor = GVAR(armorCache) get _key; +private _return = GVAR(armorCache) get _key; -if (isNil "_armor") then { - _armor = 0; +if (isNil "_return") then { + private _armor = 0; + private _armorScaled = 0; private _passThrough = 1; TRACE_2("Cache miss",_item,_hitpoint); if ("" in [_item, _hitpoint]) exitWith { - GVAR(armorCache) set [_key, _armor]; + GVAR(armorCache) set [_key, [_armor, _armorScaled]]; }; private _itemInfo = configFile >> "CfgWeapons" >> _item >> "ItemInfo"; @@ -53,9 +54,10 @@ if (isNil "_armor") then { // Scale armor using passthrough to fix explosive-resistant armor (#9063) // Skip scaling for items that don't cover the hitpoint to prevent infinite armor if (_armor isNotEqualTo 0) then { - _armor = (log (_armor / _passThrough)) * 10; + _armorScaled = (log (_armor / _passThrough)) * 10; }; - GVAR(armorCache) set [_key, _armor]; + _return = [_armor, _armorScaled]; + GVAR(armorCache) set [_key, _return]; }; -_armor // return +_return // return diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index be6e5104485..52febc996f9 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -34,9 +34,11 @@ if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), t private _newDamage = _damage - _oldDamage; // Get scaled armor value of hitpoint and calculate damage before armor // We scale using passThrough to handle explosive-resistant armor properly, fixing #9063 -private _armor = [_unit, _hitpoint] call FUNC(getHitpointArmor); +// We need both realDamage and realDamageScaled so sorting works properly +[_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; -TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); +private _realDamageScaled = _newDamage * _armorScaled; +TRACE_5("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_realDamageScaled); // Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs // Damage occurs in consistent increments @@ -74,51 +76,53 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; - private _damageStructural = _unit getVariable [QGVAR($#structural), [0,0]]; + private _damageStructural = _unit getVariable [QGVAR($#structural), [0,0,0]]; // --- Head private _damageHead = [ - _unit getVariable [QGVAR($HitFace), [0,0]], - _unit getVariable [QGVAR($HitNeck), [0,0]], - _unit getVariable [QGVAR($HitHead), [0,0]] + _unit getVariable [QGVAR($HitFace), [0,0,0]], + _unit getVariable [QGVAR($HitNeck), [0,0,0]], + _unit getVariable [QGVAR($HitHead), [0,0,0]] ]; _damageHead sort false; _damageHead = _damageHead select 0; // --- Body private _damageBody = [ - _unit getVariable [QGVAR($HitPelvis), [0,0]], - _unit getVariable [QGVAR($HitAbdomen), [0,0]], - _unit getVariable [QGVAR($HitDiaphragm), [0,0]], - _unit getVariable [QGVAR($HitChest), [0,0]] + _unit getVariable [QGVAR($HitPelvis), [0,0,0]], + _unit getVariable [QGVAR($HitAbdomen), [0,0,0]], + _unit getVariable [QGVAR($HitDiaphragm), [0,0,0]], + _unit getVariable [QGVAR($HitChest), [0,0,0]] // HitBody removed as it's a placeholder hitpoint and the high armor value (1000) throws the calculations off ]; _damageBody sort false; _damageBody = _damageBody select 0; // --- Arms and Legs - private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), [0,0]]; - private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), [0,0]]; - private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), [0,0]]; - private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), [0,0]]; + private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), [0,0,0]]; + private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), [0,0,0]]; + private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), [0,0,0]]; + private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), [0,0,0]]; // Find hit point that received the maximum damage // Priority used for sorting if incoming damage is equal + // _realDamage, priority, _newDamage, body part name private _allDamages = [ - [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, "Head"], - [_damageBody select 0, PRIORITY_BODY, _damageBody select 1, "Body"], - [_damageLeftArm select 0, PRIORITY_LEFT_ARM, _damageLeftArm select 1, "LeftArm"], - [_damageRightArm select 0, PRIORITY_RIGHT_ARM, _damageRightArm select 1, "RightArm"], - [_damageLeftLeg select 0, PRIORITY_LEFT_LEG, _damageLeftLeg select 1, "LeftLeg"], - [_damageRightLeg select 0, PRIORITY_RIGHT_LEG, _damageRightLeg select 1, "RightLeg"], - [_damageStructural select 0, PRIORITY_STRUCTURAL, _damageStructural select 1, "#structural"] + [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, _damageHead select 2, "Head"], + [_damageBody select 0, PRIORITY_BODY, _damageBody select 1, _damageBody select 2, "Body"], + [_damageLeftArm select 0, PRIORITY_LEFT_ARM, _damageLeftArm select 1, _damageLeftArm select 2, "LeftArm"], + [_damageRightArm select 0, PRIORITY_RIGHT_ARM, _damageRightArm select 1, _damageRightArm select 2, "RightArm"], + [_damageLeftLeg select 0, PRIORITY_LEFT_LEG, _damageLeftLeg select 1, _damageLeftLeg select 2, "LeftLeg"], + [_damageRightLeg select 0, PRIORITY_RIGHT_LEG, _damageRightLeg select 1, _damageRightLeg select 2, "RightLeg"], + [_damageStructural select 0, PRIORITY_STRUCTURAL, _damageStructural select 1, _damageStructural select 2, "#structural"] ]; TRACE_2("incoming",_allDamages,_damageStructural); _allDamages sort false; // We only need real damage at this point, divide by 10 to use engine range of 0-1 (or higher for really high damage) - _allDamages = _allDamages apply {[(_x select 0) / 10, _x select 3]}; + // _newDamage is maintained for compatibility + _allDamages = _allDamages apply {[(_x select 3) / 10, _x select 4, _x select 0]}; // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them @@ -169,7 +173,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { }; // Damages are stored for "ace_hdbracket" event triggered last -_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage, _realDamageScaled]]; // Engine damage to these hitpoints controls blood visuals, limping, weapon sway // Handled in fnc_damageBodyPart, persist here From 27ef26f061c9ca53eb90501ab8672bd3c7680eae Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 14 Jun 2023 01:22:59 -0300 Subject: [PATCH 09/30] whitespace --- addons/medical_engine/functions/fnc_getHitpointArmor.sqf | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf index 3e4c57e680d..6d9035f00ef 100644 --- a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf +++ b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf @@ -37,6 +37,7 @@ _unit getVariable [_var, ["", 0, 0]] params ["_prevRags", "_armor", "_armorScale if (_rags != _prevRags) then { _armor = 0; _armorScaled = 0; + { ([_x, _hitpoint] call FUNC(getItemArmor)) params ["_itemArmor", "_itemArmorScaled"]; _armor = _armor + _itemArmor; From 0098ecb5ac1404421aefdda09b8c4687483cca8c Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 14 Jun 2023 01:24:14 -0300 Subject: [PATCH 10/30] comment --- addons/medical_engine/functions/fnc_handleDamage.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 52febc996f9..4559eba31ee 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -106,7 +106,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Find hit point that received the maximum damage // Priority used for sorting if incoming damage is equal - // _realDamage, priority, _newDamage, body part name + // _realDamage, priority, _newDamage, _realDamageScaled, body part name private _allDamages = [ [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, _damageHead select 2, "Head"], [_damageBody select 0, PRIORITY_BODY, _damageBody select 1, _damageBody select 2, "Body"], From 92d636dec0eaf89f7e22279c99a67f900b1fc99a Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 14 Jun 2023 03:33:34 -0300 Subject: [PATCH 11/30] fix function header --- addons/medical_engine/functions/fnc_getHitpointArmor.sqf | 2 +- addons/medical_engine/functions/fnc_getItemArmor.sqf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf index 6d9035f00ef..9ddc2cfb0b0 100644 --- a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf +++ b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Pterolatypus + * Author: Pterolatypus, Salluci * Checks a unit's equipment to calculate the total armor on a hitpoint. * * Arguments: diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index 6094fbde1d9..4049b8ff2b2 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" /* * Author: Pterolatypus, Salluci - * Returns the scaled armor value the given item provides to a particular hitpoint, either from a cache or by reading the item config. + * Returns the regular and scaled armor values the given item provides to a particular hitpoint, either from a cache or by reading the item config. * * Arguments: * 0: Item Class * 1: Hitpoint * * Return Value: - * Scaled item armor for the given hitpoint + * Regular and scaled item armor for the given hitpoint * * Example: * ["V_PlateCarrier_rgr", "HitChest"] call ace_medical_engine_fnc_getItemArmor From cdf6520f922146afca7cfefd03ebe7b57a75df82 Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 14 Jun 2023 17:27:52 -0300 Subject: [PATCH 12/30] fix infinite armor when no item equipped --- addons/medical_engine/functions/fnc_getItemArmor.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index 4049b8ff2b2..9eade2f0871 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -27,7 +27,8 @@ if (isNil "_return") then { private _passThrough = 1; TRACE_2("Cache miss",_item,_hitpoint); if ("" in [_item, _hitpoint]) exitWith { - GVAR(armorCache) set [_key, [_armor, _armorScaled]]; + _return = [_armor, _armorScaled]; + GVAR(armorCache) set [_key, _return]; }; private _itemInfo = configFile >> "CfgWeapons" >> _item >> "ItemInfo"; From f925f0dd4140358372cbeee8992ca243e4261662 Mon Sep 17 00:00:00 2001 From: Salluci Date: Sat, 24 Jun 2023 07:52:51 +0300 Subject: [PATCH 13/30] modify condition & handling for vehicle explosion --- .../functions/fnc_handleDamage.sqf | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 68798d38dad..dde2845ca08 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -67,27 +67,18 @@ if ( 0 }; -// Being inside an exploding vehicle doesn't trigger for each hitpoint -// It seems to fire twice with ammo type "FuelExplosion" or "FuelExplosionBig" +// Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint +// This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions +// Triggers twice, but that doesn't matter if ( _hitPoint isEqualTo "#structural" && - {_ammo isKindOf "FuelExplosion"} && {_vehicle != _unit} && - {_damage == 1} + {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0} ) exitwith { - // triggers twice, so do half damage each time. not very important as it's basically always lethal - private _hit = GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "indirectHit", 10)/2; - private _uniform = uniform _unit; - if (_uniform isEqualTo "") then { - _uniform = getText (configOf _unit >> "nakedUniform"); - }; - private _uniformClass = GET_STRING(configFile >> "CfgWeapons" >> _uniform >> "ItemInfo" >> "uniformClass", "U_BasicBody"); + _newDamage = abs _newDamage; // damage can sometimes be negative (why?) private _damages = []; { - private _armor = [_unit, _x] call FUNC(getHitpointArmor); - // would be nice to move this into getHitpointArmor - private _shielding = GET_NUMBER(configFile >> "CfgVehicles" >> _uniformClass >> "Hitpoints" >> _x >> "explosionShielding", 1); - _damages pushBack [_hit*_shielding/_armor, ALL_BODY_PARTS select _forEachIndex, _hit*_shielding]; + _damages pushBack [_newDamage, ALL_BODY_PARTS select _forEachIndex, _newDamage]; } forEach ALL_HITPOINTS; TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); [QEGVAR(medical,woundReceived), [_unit, _damages, _unit, _ammo]] call CBA_fnc_localEvent; @@ -144,7 +135,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { _allDamages sort false; _allDamages = _allDamages apply {[_x select 2, _x select 3, _x select 0]}; - + // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them if (_ammo isEqualTo "") then { From 454633fcb71b3a60b0919d6787357b7537ea1b10 Mon Sep 17 00:00:00 2001 From: Salluci Date: Tue, 27 Jun 2023 04:09:55 +0300 Subject: [PATCH 14/30] add vehiclehit woundHandler --- .../medical_damage/ACE_Medical_Injuries.hpp | 12 +++++++ addons/medical_damage/XEH_PREP.hpp | 1 + .../functions/fnc_woundsHandlerVehiclehit.sqf | 34 +++++++++++++++++++ .../functions/fnc_handleDamage.sqf | 8 ++--- 4 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index f09008880ba..05ffc82c63c 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -167,6 +167,18 @@ class ACE_Medical_Injuries { painMultiplier = 0.9; }; }; + class vehiclehit: explosive { + // vehicle explosions are usually caused by explosive damage and should behave similarly to shell damage + class woundHandlers: woundHandlers { + GVAR(vehiclehit) = QFUNC(woundsHandlerVehiclehit); + }; + class VelocityWound { + weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}}; + }; + class PunctureWound { + weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}}; + }; + }; class vehiclecrash { thresholds[] = {{1.5, 3}, {1.5, 2}, {1, 2}, {1, 1}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index 6df53fb3091..4886d3fac44 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -9,3 +9,4 @@ PREP(woundReceived); PREP(woundsHandlerBase); PREP(woundsHandlerBurning); PREP(woundsHandlerVehiclecrash); +PREP(woundsHandlerVehiclehit) diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf new file mode 100644 index 00000000000..488656e3c5f --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "#structural", 1.5]], "vehicleHit"] call ace_medical_damage_fnc_woundsHandlerVehiclehit + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerVehicleHit",_unit,_allDamages,_typeOfDamage); + +_allDamages sort false; +private _damageToApply = _allDamages select 0 select 0; + +private _newDamages = []; + +// randomize quantity and hitpoints +for "_i" from 1 to (round random [2, 3, 8]) do { + // legs and body are more likely to be hit: they're typically in more cramped sections of the vehicle + _newDamages pushBack [_damageToApply, selectRandomWeighted ["head", 2, "body", 3, "leftarm", 1, "rightarm", 1, "leftleg", 3, "rightleg", 3], _damageToApply]; +}; + +TRACE_1("Vehicle explosion handled, passing damage", _newDamages); +[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index dde2845ca08..c5043da8449 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -73,15 +73,11 @@ if ( if ( _hitPoint isEqualTo "#structural" && {_vehicle != _unit} && - {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0} + {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0 || _ammo isKindOf "SubmunitionBase"} ) exitwith { _newDamage = abs _newDamage; // damage can sometimes be negative (why?) - private _damages = []; - { - _damages pushBack [_newDamage, ALL_BODY_PARTS select _forEachIndex, _newDamage]; - } forEach ALL_HITPOINTS; TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); - [QEGVAR(medical,woundReceived), [_unit, _damages, _unit, _ammo]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehiclehit"]] call CBA_fnc_localEvent; 0 }; From 182f9468d2be73ab8ac5b527134b924eeee7071d Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 28 Jun 2023 02:44:48 +0300 Subject: [PATCH 15/30] finalize --- .../medical_damage/ACE_Medical_Injuries.hpp | 10 +---- addons/medical_damage/XEH_PREP.hpp | 2 +- .../fnc_woundsHandlerVehicleexplosion.sqf | 40 +++++++++++++++++++ .../functions/fnc_woundsHandlerVehiclehit.sqf | 34 ---------------- .../functions/fnc_handleDamage.sqf | 6 +-- 5 files changed, 46 insertions(+), 46 deletions(-) create mode 100644 addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf delete mode 100644 addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index 05ffc82c63c..73dd6ca93e3 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -167,16 +167,10 @@ class ACE_Medical_Injuries { painMultiplier = 0.9; }; }; - class vehiclehit: explosive { + class vehicleexplosion: shell { // vehicle explosions are usually caused by explosive damage and should behave similarly to shell damage class woundHandlers: woundHandlers { - GVAR(vehiclehit) = QFUNC(woundsHandlerVehiclehit); - }; - class VelocityWound { - weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}}; - }; - class PunctureWound { - weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}}; + GVAR(vehiclehit) = QFUNC(woundsHandlerVehicleexplosion); }; }; class vehiclecrash { diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index 4886d3fac44..688e9010f68 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -9,4 +9,4 @@ PREP(woundReceived); PREP(woundsHandlerBase); PREP(woundsHandlerBurning); PREP(woundsHandlerVehiclecrash); -PREP(woundsHandlerVehiclehit) +PREP(woundsHandlerVehicleexplosion); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf new file mode 100644 index 00000000000..db8560341ca --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "#structural", 1.5]], "vehicleExplosion"] call ace_medical_damage_fnc_woundsHandlerVehicleexplosion + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerVehicleExplosion",_unit,_allDamages,_typeOfDamage); + +// this should only trigger for hits to just structural +if (count _allDamages > 1) exitWith {_this}; + +// damage can sometimes be negative (why?) +// damage to structural is low unless it's a very large explosion, in which case it is typically >= 1 +private _damageToApply = sqrt (abs (_allDamages select 0 select 0)); + +private _newDamages = []; + +{ + // randomize hitpoints, more hits for more damage + if (_damageToApply >= random 0.75) then { + private _damageToLimb = _damageToApply * random [0.75, 1, 1.5]; + _newDamages pushBack [_damageToApply, _x, _damageToApply] + }; +} forEach ALL_BODY_PARTS; + +TRACE_1("Vehicle explosion handled, passing damage", _newDamages); +[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf deleted file mode 100644 index 488656e3c5f..00000000000 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf +++ /dev/null @@ -1,34 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Pterolatypus, LinkIsGrim - * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint - * - * Arguments: - * 0: Unit That Was Hit - * 1: Damage done to each body part - * 2: Type of the damage done - * - * Return Value: - * None - * - * Example: - * [player, [[0.5, "#structural", 1.5]], "vehicleHit"] call ace_medical_damage_fnc_woundsHandlerVehiclehit - * - * Public: No - */ -params ["_unit", "_allDamages", "_typeOfDamage"]; -TRACE_3("woundsHandlerVehicleHit",_unit,_allDamages,_typeOfDamage); - -_allDamages sort false; -private _damageToApply = _allDamages select 0 select 0; - -private _newDamages = []; - -// randomize quantity and hitpoints -for "_i" from 1 to (round random [2, 3, 8]) do { - // legs and body are more likely to be hit: they're typically in more cramped sections of the vehicle - _newDamages pushBack [_damageToApply, selectRandomWeighted ["head", 2, "body", 3, "leftarm", 1, "rightarm", 1, "leftleg", 3, "rightleg", 3], _damageToApply]; -}; - -TRACE_1("Vehicle explosion handled, passing damage", _newDamages); -[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index c5043da8449..675a95136d1 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -73,11 +73,11 @@ if ( if ( _hitPoint isEqualTo "#structural" && {_vehicle != _unit} && - {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0 || _ammo isKindOf "SubmunitionBase"} + {_ammo isNotEqualTo ""} && + {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0} ) exitwith { - _newDamage = abs _newDamage; // damage can sometimes be negative (why?) TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); - [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehiclehit"]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehicleexplosion"]] call CBA_fnc_localEvent; 0 }; From 109ec335ae1090de56a8720f76ae871151d59057 Mon Sep 17 00:00:00 2001 From: Salluci Date: Tue, 27 Jun 2023 04:09:55 +0300 Subject: [PATCH 16/30] add vehiclehit woundHandler --- .../medical_damage/ACE_Medical_Injuries.hpp | 12 +++++++ addons/medical_damage/XEH_PREP.hpp | 1 + .../functions/fnc_woundsHandlerVehiclehit.sqf | 34 +++++++++++++++++++ .../functions/fnc_handleDamage.sqf | 8 ++--- 4 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index f09008880ba..05ffc82c63c 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -167,6 +167,18 @@ class ACE_Medical_Injuries { painMultiplier = 0.9; }; }; + class vehiclehit: explosive { + // vehicle explosions are usually caused by explosive damage and should behave similarly to shell damage + class woundHandlers: woundHandlers { + GVAR(vehiclehit) = QFUNC(woundsHandlerVehiclehit); + }; + class VelocityWound { + weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}}; + }; + class PunctureWound { + weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}}; + }; + }; class vehiclecrash { thresholds[] = {{1.5, 3}, {1.5, 2}, {1, 2}, {1, 1}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered selectionSpecific = 0; diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index 6df53fb3091..4886d3fac44 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -9,3 +9,4 @@ PREP(woundReceived); PREP(woundsHandlerBase); PREP(woundsHandlerBurning); PREP(woundsHandlerVehiclecrash); +PREP(woundsHandlerVehiclehit) diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf new file mode 100644 index 00000000000..488656e3c5f --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -0,0 +1,34 @@ +#include "script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "#structural", 1.5]], "vehicleHit"] call ace_medical_damage_fnc_woundsHandlerVehiclehit + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerVehicleHit",_unit,_allDamages,_typeOfDamage); + +_allDamages sort false; +private _damageToApply = _allDamages select 0 select 0; + +private _newDamages = []; + +// randomize quantity and hitpoints +for "_i" from 1 to (round random [2, 3, 8]) do { + // legs and body are more likely to be hit: they're typically in more cramped sections of the vehicle + _newDamages pushBack [_damageToApply, selectRandomWeighted ["head", 2, "body", 3, "leftarm", 1, "rightarm", 1, "leftleg", 3, "rightleg", 3], _damageToApply]; +}; + +TRACE_1("Vehicle explosion handled, passing damage", _newDamages); +[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index dde2845ca08..c5043da8449 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -73,15 +73,11 @@ if ( if ( _hitPoint isEqualTo "#structural" && {_vehicle != _unit} && - {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0} + {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0 || _ammo isKindOf "SubmunitionBase"} ) exitwith { _newDamage = abs _newDamage; // damage can sometimes be negative (why?) - private _damages = []; - { - _damages pushBack [_newDamage, ALL_BODY_PARTS select _forEachIndex, _newDamage]; - } forEach ALL_HITPOINTS; TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); - [QEGVAR(medical,woundReceived), [_unit, _damages, _unit, _ammo]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehiclehit"]] call CBA_fnc_localEvent; 0 }; From 7ba4a64bfc752535dd7ba1e9cb9318eab2ef97c3 Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 28 Jun 2023 02:44:48 +0300 Subject: [PATCH 17/30] finalize --- .../medical_damage/ACE_Medical_Injuries.hpp | 10 +---- addons/medical_damage/XEH_PREP.hpp | 2 +- .../fnc_woundsHandlerVehicleexplosion.sqf | 40 +++++++++++++++++++ .../functions/fnc_woundsHandlerVehiclehit.sqf | 34 ---------------- .../functions/fnc_handleDamage.sqf | 6 +-- 5 files changed, 46 insertions(+), 46 deletions(-) create mode 100644 addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf delete mode 100644 addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index 05ffc82c63c..73dd6ca93e3 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -167,16 +167,10 @@ class ACE_Medical_Injuries { painMultiplier = 0.9; }; }; - class vehiclehit: explosive { + class vehicleexplosion: shell { // vehicle explosions are usually caused by explosive damage and should behave similarly to shell damage class woundHandlers: woundHandlers { - GVAR(vehiclehit) = QFUNC(woundsHandlerVehiclehit); - }; - class VelocityWound { - weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}}; - }; - class PunctureWound { - weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}}; + GVAR(vehiclehit) = QFUNC(woundsHandlerVehicleexplosion); }; }; class vehiclecrash { diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index 4886d3fac44..688e9010f68 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -9,4 +9,4 @@ PREP(woundReceived); PREP(woundsHandlerBase); PREP(woundsHandlerBurning); PREP(woundsHandlerVehiclecrash); -PREP(woundsHandlerVehiclehit) +PREP(woundsHandlerVehicleexplosion); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf new file mode 100644 index 00000000000..db8560341ca --- /dev/null +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf @@ -0,0 +1,40 @@ +#include "script_component.hpp" +/* + * Author: Pterolatypus, LinkIsGrim + * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint + * + * Arguments: + * 0: Unit That Was Hit + * 1: Damage done to each body part + * 2: Type of the damage done + * + * Return Value: + * None + * + * Example: + * [player, [[0.5, "#structural", 1.5]], "vehicleExplosion"] call ace_medical_damage_fnc_woundsHandlerVehicleexplosion + * + * Public: No + */ +params ["_unit", "_allDamages", "_typeOfDamage"]; +TRACE_3("woundsHandlerVehicleExplosion",_unit,_allDamages,_typeOfDamage); + +// this should only trigger for hits to just structural +if (count _allDamages > 1) exitWith {_this}; + +// damage can sometimes be negative (why?) +// damage to structural is low unless it's a very large explosion, in which case it is typically >= 1 +private _damageToApply = sqrt (abs (_allDamages select 0 select 0)); + +private _newDamages = []; + +{ + // randomize hitpoints, more hits for more damage + if (_damageToApply >= random 0.75) then { + private _damageToLimb = _damageToApply * random [0.75, 1, 1.5]; + _newDamages pushBack [_damageToApply, _x, _damageToApply] + }; +} forEach ALL_BODY_PARTS; + +TRACE_1("Vehicle explosion handled, passing damage", _newDamages); +[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf deleted file mode 100644 index 488656e3c5f..00000000000 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf +++ /dev/null @@ -1,34 +0,0 @@ -#include "script_component.hpp" -/* - * Author: Pterolatypus, LinkIsGrim - * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint - * - * Arguments: - * 0: Unit That Was Hit - * 1: Damage done to each body part - * 2: Type of the damage done - * - * Return Value: - * None - * - * Example: - * [player, [[0.5, "#structural", 1.5]], "vehicleHit"] call ace_medical_damage_fnc_woundsHandlerVehiclehit - * - * Public: No - */ -params ["_unit", "_allDamages", "_typeOfDamage"]; -TRACE_3("woundsHandlerVehicleHit",_unit,_allDamages,_typeOfDamage); - -_allDamages sort false; -private _damageToApply = _allDamages select 0 select 0; - -private _newDamages = []; - -// randomize quantity and hitpoints -for "_i" from 1 to (round random [2, 3, 8]) do { - // legs and body are more likely to be hit: they're typically in more cramped sections of the vehicle - _newDamages pushBack [_damageToApply, selectRandomWeighted ["head", 2, "body", 3, "leftarm", 1, "rightarm", 1, "leftleg", 3, "rightleg", 3], _damageToApply]; -}; - -TRACE_1("Vehicle explosion handled, passing damage", _newDamages); -[_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index c5043da8449..675a95136d1 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -73,11 +73,11 @@ if ( if ( _hitPoint isEqualTo "#structural" && {_vehicle != _unit} && - {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0 || _ammo isKindOf "SubmunitionBase"} + {_ammo isNotEqualTo ""} && + {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0} ) exitwith { - _newDamage = abs _newDamage; // damage can sometimes be negative (why?) TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); - [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehiclehit"]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehicleexplosion"]] call CBA_fnc_localEvent; 0 }; From 34a4b24232d6b33e822ab092ea9fbce7b618abf4 Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 28 Jun 2023 17:08:48 +0300 Subject: [PATCH 18/30] cleanup --- .../functions/fnc_handleDamage.sqf | 50 +++++++++---------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 4559eba31ee..92deb1f0f27 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -33,12 +33,12 @@ if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), t private _newDamage = _damage - _oldDamage; // Get scaled armor value of hitpoint and calculate damage before armor -// We scale using passThrough to handle explosive-resistant armor properly, fixing #9063 -// We need both realDamage and realDamageScaled so sorting works properly +// We scale using passThrough to handle explosive-resistant armor properly (#9063) +// We need realDamage to determine which limb was hit correctly [_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; -private _realDamageScaled = _newDamage * _armorScaled; -TRACE_5("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_realDamageScaled); +_newDamage = _newDamage * (_armor/_armorScaled); +TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); // Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs // Damage occurs in consistent increments @@ -76,11 +76,11 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; - private _damageStructural = _unit getVariable [QGVAR($#structural), [0,0,0]]; + private _damageStructural = _unit getVariable [QGVAR($#structural), [0,0]]; // --- Head private _damageHead = [ - _unit getVariable [QGVAR($HitFace), [0,0,0]], + _unit getVariable [QGVAR($HitFace), [0,0]], _unit getVariable [QGVAR($HitNeck), [0,0,0]], _unit getVariable [QGVAR($HitHead), [0,0,0]] ]; @@ -89,40 +89,38 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // --- Body private _damageBody = [ - _unit getVariable [QGVAR($HitPelvis), [0,0,0]], - _unit getVariable [QGVAR($HitAbdomen), [0,0,0]], - _unit getVariable [QGVAR($HitDiaphragm), [0,0,0]], - _unit getVariable [QGVAR($HitChest), [0,0,0]] + _unit getVariable [QGVAR($HitPelvis), [0,0]], + _unit getVariable [QGVAR($HitAbdomen), [0,0]], + _unit getVariable [QGVAR($HitDiaphragm), [0,0]], + _unit getVariable [QGVAR($HitChest), [0,0]] // HitBody removed as it's a placeholder hitpoint and the high armor value (1000) throws the calculations off ]; _damageBody sort false; _damageBody = _damageBody select 0; // --- Arms and Legs - private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), [0,0,0]]; - private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), [0,0,0]]; - private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), [0,0,0]]; - private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), [0,0,0]]; + private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), [0,0]]; + private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), [0,0]]; + private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), [0,0]]; + private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), [0,0]]; // Find hit point that received the maximum damage // Priority used for sorting if incoming damage is equal - // _realDamage, priority, _newDamage, _realDamageScaled, body part name + // _realDamage, priority, _newDamage, body part name private _allDamages = [ - [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, _damageHead select 2, "Head"], - [_damageBody select 0, PRIORITY_BODY, _damageBody select 1, _damageBody select 2, "Body"], - [_damageLeftArm select 0, PRIORITY_LEFT_ARM, _damageLeftArm select 1, _damageLeftArm select 2, "LeftArm"], - [_damageRightArm select 0, PRIORITY_RIGHT_ARM, _damageRightArm select 1, _damageRightArm select 2, "RightArm"], - [_damageLeftLeg select 0, PRIORITY_LEFT_LEG, _damageLeftLeg select 1, _damageLeftLeg select 2, "LeftLeg"], - [_damageRightLeg select 0, PRIORITY_RIGHT_LEG, _damageRightLeg select 1, _damageRightLeg select 2, "RightLeg"], - [_damageStructural select 0, PRIORITY_STRUCTURAL, _damageStructural select 1, _damageStructural select 2, "#structural"] + [_damageHead select 0, PRIORITY_HEAD, _damageHead select 1, "Head"], + [_damageBody select 0, PRIORITY_BODY, _damageBody select 1, "Body"], + [_damageLeftArm select 0, PRIORITY_LEFT_ARM, _damageLeftArm select 1, "LeftArm"], + [_damageRightArm select 0, PRIORITY_RIGHT_ARM, _damageRightArm select 1, "RightArm"], + [_damageLeftLeg select 0, PRIORITY_LEFT_LEG, _damageLeftLeg select 1, "LeftLeg"], + [_damageRightLeg select 0, PRIORITY_RIGHT_LEG, _damageRightLeg select 1, "RightLeg"], + [_damageStructural select 0, PRIORITY_STRUCTURAL, _damageStructural select 1, "#structural"] ]; TRACE_2("incoming",_allDamages,_damageStructural); _allDamages sort false; - // We only need real damage at this point, divide by 10 to use engine range of 0-1 (or higher for really high damage) - // _newDamage is maintained for compatibility - _allDamages = _allDamages apply {[(_x select 3) / 10, _x select 4, _x select 0]}; + _allDamages = _allDamages apply {[_x select 2, _x select 3, _x select 0]}; // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them @@ -173,7 +171,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { }; // Damages are stored for "ace_hdbracket" event triggered last -_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage, _realDamageScaled]]; +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; // Engine damage to these hitpoints controls blood visuals, limping, weapon sway // Handled in fnc_damageBodyPart, persist here From 2b3287068678f50cd32168affd0ff454bca6c627 Mon Sep 17 00:00:00 2001 From: Salluci Date: Wed, 28 Jun 2023 17:14:52 +0300 Subject: [PATCH 19/30] more cleanup --- addons/medical_engine/functions/fnc_handleDamage.sqf | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 92deb1f0f27..649c06cd710 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -38,7 +38,7 @@ private _newDamage = _damage - _oldDamage; [_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; _newDamage = _newDamage * (_armor/_armorScaled); -TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); +TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); // Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs // Damage occurs in consistent increments @@ -81,8 +81,8 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // --- Head private _damageHead = [ _unit getVariable [QGVAR($HitFace), [0,0]], - _unit getVariable [QGVAR($HitNeck), [0,0,0]], - _unit getVariable [QGVAR($HitHead), [0,0,0]] + _unit getVariable [QGVAR($HitNeck), [0,0]], + _unit getVariable [QGVAR($HitHead), [0,0]] ]; _damageHead sort false; _damageHead = _damageHead select 0; @@ -119,7 +119,6 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { TRACE_2("incoming",_allDamages,_damageStructural); _allDamages sort false; - _allDamages = _allDamages apply {[_x select 2, _x select 3, _x select 0]}; // Environmental damage sources all have empty ammo string From aafef614ddc8b7843ee7cb134868e9cedc8f64b6 Mon Sep 17 00:00:00 2001 From: Salluci Date: Thu, 6 Jul 2023 06:53:47 +0300 Subject: [PATCH 20/30] name --- addons/medical_engine/functions/fnc_getHitpointArmor.sqf | 2 +- addons/medical_engine/functions/fnc_getItemArmor.sqf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf index 9ddc2cfb0b0..6b9f873b3dd 100644 --- a/addons/medical_engine/functions/fnc_getHitpointArmor.sqf +++ b/addons/medical_engine/functions/fnc_getHitpointArmor.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Pterolatypus, Salluci + * Author: Pterolatypus, LinkIsGrim * Checks a unit's equipment to calculate the total armor on a hitpoint. * * Arguments: diff --git a/addons/medical_engine/functions/fnc_getItemArmor.sqf b/addons/medical_engine/functions/fnc_getItemArmor.sqf index 9eade2f0871..134bd4bfe81 100644 --- a/addons/medical_engine/functions/fnc_getItemArmor.sqf +++ b/addons/medical_engine/functions/fnc_getItemArmor.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: Pterolatypus, Salluci + * Author: Pterolatypus, LinkIsGrim * Returns the regular and scaled armor values the given item provides to a particular hitpoint, either from a cache or by reading the item config. * * Arguments: From f93c4b36acf2448e36a2565216ae34baadb293c6 Mon Sep 17 00:00:00 2001 From: Salluci Date: Sun, 9 Jul 2023 18:07:35 +0300 Subject: [PATCH 21/30] randomize hitpoints --- .../functions/fnc_woundsHandlerVehicleexplosion.sqf | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf index db8560341ca..a88e8010d77 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf @@ -24,17 +24,14 @@ if (count _allDamages > 1) exitWith {_this}; // damage can sometimes be negative (why?) // damage to structural is low unless it's a very large explosion, in which case it is typically >= 1 -private _damageToApply = sqrt (abs (_allDamages select 0 select 0)); +private _damageToApply = (abs (_allDamages select 0 select 0)); private _newDamages = []; -{ - // randomize hitpoints, more hits for more damage - if (_damageToApply >= random 0.75) then { - private _damageToLimb = _damageToApply * random [0.75, 1, 1.5]; - _newDamages pushBack [_damageToApply, _x, _damageToApply] - }; -} forEach ALL_BODY_PARTS; +// hitpoints are randomized, more damage means more wounds in different body parts +for "_i" from 1 to (_damageToApply * 6) do { + _newDamages pushBack [_damageToApply, selectRandom ALL_BODY_PARTS, _damageToApply] +}; TRACE_1("Vehicle explosion handled, passing damage", _newDamages); [_unit, _newDamages, _typeOfDamage] //return From e608f9428e49deb66fe0d7078ab6ffb27467b646 Mon Sep 17 00:00:00 2001 From: Salluci Date: Sun, 9 Jul 2023 19:00:47 +0300 Subject: [PATCH 22/30] finalize --- .../medical_damage/ACE_Medical_Injuries.hpp | 7 +++--- addons/medical_damage/XEH_PREP.hpp | 2 +- ...on.sqf => fnc_woundsHandlerVehiclehit.sqf} | 6 ++--- .../functions/fnc_handleDamage.sqf | 24 +++++++++++++------ 4 files changed, 25 insertions(+), 14 deletions(-) rename addons/medical_damage/functions/{fnc_woundsHandlerVehicleexplosion.sqf => fnc_woundsHandlerVehiclehit.sqf} (78%) diff --git a/addons/medical_damage/ACE_Medical_Injuries.hpp b/addons/medical_damage/ACE_Medical_Injuries.hpp index 73dd6ca93e3..8117a2c56ff 100644 --- a/addons/medical_damage/ACE_Medical_Injuries.hpp +++ b/addons/medical_damage/ACE_Medical_Injuries.hpp @@ -167,10 +167,11 @@ class ACE_Medical_Injuries { painMultiplier = 0.9; }; }; - class vehicleexplosion: shell { - // vehicle explosions are usually caused by explosive damage and should behave similarly to shell damage + class vehiclehit: explosive { + // vehicle explosions are usually caused by explosive damage and should behave similarly + thresholds[] = {{6, 3}, {4.5, 2}, {2, 2}, {0.8, 1}, {0.2, 1}, {0, 0}}; class woundHandlers: woundHandlers { - GVAR(vehiclehit) = QFUNC(woundsHandlerVehicleexplosion); + GVAR(vehiclehit) = QFUNC(woundsHandlerVehiclehit); }; }; class vehiclecrash { diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index 688e9010f68..a17e7d739c5 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -9,4 +9,4 @@ PREP(woundReceived); PREP(woundsHandlerBase); PREP(woundsHandlerBurning); PREP(woundsHandlerVehiclecrash); -PREP(woundsHandlerVehicleexplosion); +PREP(woundsHandlerVehiclehit); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf similarity index 78% rename from addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf rename to addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf index a88e8010d77..3b0c1b71c0b 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehicleexplosion.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -12,12 +12,12 @@ * None * * Example: - * [player, [[0.5, "#structural", 1.5]], "vehicleExplosion"] call ace_medical_damage_fnc_woundsHandlerVehicleexplosion + * [player, [[0.5, "#structural", 1.5]], "vehiclehit"] call ace_medical_damage_fnc_woundsHandlerVehiclehit * * Public: No */ params ["_unit", "_allDamages", "_typeOfDamage"]; -TRACE_3("woundsHandlerVehicleExplosion",_unit,_allDamages,_typeOfDamage); +TRACE_3("woundsHandlerVehiclehit",_unit,_allDamages,_typeOfDamage); // this should only trigger for hits to just structural if (count _allDamages > 1) exitWith {_this}; @@ -30,7 +30,7 @@ private _newDamages = []; // hitpoints are randomized, more damage means more wounds in different body parts for "_i" from 1 to (_damageToApply * 6) do { - _newDamages pushBack [_damageToApply, selectRandom ALL_BODY_PARTS, _damageToApply] + _newDamages pushBack [_damageToApply * 6, selectRandom ALL_BODY_PARTS, _damageToApply * 6] }; TRACE_1("Vehicle explosion handled, passing damage", _newDamages); diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 95f41f67cd5..2c7ccefcc0c 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -53,14 +53,16 @@ if ( 0 }; +// Faster than (vehicle _unit) != _unit, also handles dead units +private _inVehicle = !(isNull objectParent _unit); + // Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs // It does fire the EH multiple times, but this seems to scale with the intensity of the crash -private _vehicle = vehicle _unit; if ( EGVAR(medical,enableVehicleCrashes) && {_hitPoint isEqualTo "#structural"} && {_ammo isEqualTo ""} && - {_vehicle != _unit} && + {_inVehicle} && {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { @@ -72,15 +74,23 @@ if ( // Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint // This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions -// Triggers twice, but that doesn't matter +// Triggers twice, but that doesn't matter as damage is low if ( _hitPoint isEqualTo "#structural" && - {_vehicle != _unit} && + {_inVehicle} && {_ammo isNotEqualTo ""} && - {GET_NUMBER(configFile >> "CfgAmmo" >> _ammo >> "explosive", 0) > 0} + { + private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; + GET_NUMBER(_ammoCfg >> "explosive", 0) > 0 || + {GET_NUMBER(_ammoCfg >> "indirectHit", 0) > 0} + } ) exitwith { - TRACE_6("Vehicle explosion",_unit,_shooter,_instigator,_damage,_newDamage,_damages); - [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _unit, "vehicleexplosion"]] call CBA_fnc_localEvent; + TRACE_6("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage,_damages); + + _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; + _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; + + [QEGVAR(medical,woundReceived), [_unit, [[_newDamage, _hitPoint, _newDamage]], _shooter, "vehiclehit"]] call CBA_fnc_localEvent; 0 }; From 260e1c315e82081cc67d0cb5cdfae240d91ced5f Mon Sep 17 00:00:00 2001 From: Salluci Date: Sun, 9 Jul 2023 19:13:38 +0300 Subject: [PATCH 23/30] don't scale structural damage --- addons/medical_engine/functions/fnc_handleDamage.sqf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 649c06cd710..20c5ad05966 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -37,7 +37,9 @@ private _newDamage = _damage - _oldDamage; // We need realDamage to determine which limb was hit correctly [_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; -_newDamage = _newDamage * (_armor/_armorScaled); +if (_hitPoint isNotEqualTo "#structural") then { + _newDamage = _newDamage * (_armor/_armorScaled); +}; TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); // Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs From 69c01bdb38eda89c55c1e86f5e68de78edaac1d8 Mon Sep 17 00:00:00 2001 From: LinkIsGrim Date: Thu, 31 Aug 2023 18:44:04 -0400 Subject: [PATCH 24/30] fix undefined var --- addons/medical_engine/functions/fnc_handleDamage.sqf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 4bdc2c3b2f3..18072b61c6a 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -55,8 +55,8 @@ if ( 0 }; -// Faster than (vehicle _unit) != _unit, also handles dead units -private _inVehicle = !(isNull objectParent _unit); +// Faster than (vehicle _unit), also handles dead units +private _vehicle = objectParent _unit; // Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs // It does fire the EH multiple times, but this seems to scale with the intensity of the crash @@ -64,7 +64,7 @@ if ( EGVAR(medical,enableVehicleCrashes) && {_hitPoint isEqualTo "#structural"} && {_ammo isEqualTo ""} && - {_inVehicle} && + {!isNull _vehicle} && {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { @@ -79,7 +79,7 @@ if ( // Triggers twice, but that doesn't matter as damage is low if ( _hitPoint isEqualTo "#structural" && - {_inVehicle} && + {!isNull _vehicle} && {_ammo isNotEqualTo ""} && { private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; From 1f07466d76cd5ab036565e4f705d439b1dc4aa0f Mon Sep 17 00:00:00 2001 From: LinkIsGrim Date: Thu, 31 Aug 2023 19:18:26 -0400 Subject: [PATCH 25/30] remove _i --- addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf index 3b0c1b71c0b..eb6e8ab3c6f 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -29,7 +29,7 @@ private _damageToApply = (abs (_allDamages select 0 select 0)); private _newDamages = []; // hitpoints are randomized, more damage means more wounds in different body parts -for "_i" from 1 to (_damageToApply * 6) do { +for "" from 1 to (_damageToApply * 6) do { _newDamages pushBack [_damageToApply * 6, selectRandom ALL_BODY_PARTS, _damageToApply * 6] }; From f4c2925ac5fbf5e953431c0cce22d19ca142f443 Mon Sep 17 00:00:00 2001 From: LinkIsGrim Date: Wed, 6 Sep 2023 11:25:06 -0400 Subject: [PATCH 26/30] fix script error, tone down scaling --- .../medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf index eb6e8ab3c6f..f5c669fd3ce 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -29,8 +29,8 @@ private _damageToApply = (abs (_allDamages select 0 select 0)); private _newDamages = []; // hitpoints are randomized, more damage means more wounds in different body parts -for "" from 1 to (_damageToApply * 6) do { - _newDamages pushBack [_damageToApply * 6, selectRandom ALL_BODY_PARTS, _damageToApply * 6] +for "_i" from 1 to (_damageToApply * 6) do { + _newDamages pushBack [_damageToApply, selectRandom ALL_BODY_PARTS, _damageToApply] }; TRACE_1("Vehicle explosion handled, passing damage", _newDamages); From 73cc01bc694d1d59d01e8a614e93988d761967a1 Mon Sep 17 00:00:00 2001 From: LinkIsGrim Date: Wed, 6 Sep 2023 11:50:34 -0400 Subject: [PATCH 27/30] add AVD checks --- addons/medical_engine/functions/fnc_handleDamage.sqf | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 6c5aa28a868..e2899b07180 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -89,6 +89,18 @@ if ( ) exitwith { TRACE_6("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage,_damages); + // Let Advanced Vehicle Damage handle if appropriate + if ( + missionNamespace getVariable [QEGVAR(vehicle_damage,enabled), false] && + { + missionNamespace getVariable [QEGVAR(vehicle_damage,enableCarDamage), false] && {_vehicle isKindOf "Car"} || + {["Tank", "Wheeled_APC_F"] findIf {_vehicle isKindOf _x} != -1} + } + ) exitWith { + TRACE_1("Diverting to AVD",_vehicle); + 0 + }; + _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; From d89d7d1842e6319b095965f0fc982f679435e918 Mon Sep 17 00:00:00 2001 From: Grim <69561145+LinkIsGrim@users.noreply.github.com> Date: Sat, 23 Sep 2023 13:36:14 -0400 Subject: [PATCH 28/30] Update addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf Co-authored-by: PabstMirror --- addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf index f5c669fd3ce..9c4f864f97c 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: Pterolatypus, LinkIsGrim * Custom wound handler for vehicle hits and explosions, sends damage to a random hitpoint From 7cf545128746ec6c1b0a644a484a328e7de205d0 Mon Sep 17 00:00:00 2001 From: LinkIsGrim Date: Sat, 23 Sep 2023 16:30:54 -0400 Subject: [PATCH 29/30] nuke AVD crew damage handling --- .../functions/fnc_handleDamage.sqf | 12 --- addons/vehicle_damage/XEH_PREP.hpp | 1 - .../functions/fnc_injureOccupants.sqf | 76 ------------------- .../functions/fnc_processHit.sqf | 27 ------- 4 files changed, 116 deletions(-) delete mode 100644 addons/vehicle_damage/functions/fnc_injureOccupants.sqf diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index bb86e00a5bf..6483f6de648 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -91,18 +91,6 @@ if ( ) exitwith { TRACE_6("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage,_damages); - // Let Advanced Vehicle Damage handle if appropriate - if ( - missionNamespace getVariable [QEGVAR(vehicle_damage,enabled), false] && - { - missionNamespace getVariable [QEGVAR(vehicle_damage,enableCarDamage), false] && {_vehicle isKindOf "Car"} || - {["Tank", "Wheeled_APC_F"] findIf {_vehicle isKindOf _x} != -1} - } - ) exitWith { - TRACE_1("Diverting to AVD",_vehicle); - 0 - }; - _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp index 0f379e241fa..524fe6ea9dd 100644 --- a/addons/vehicle_damage/XEH_PREP.hpp +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -5,7 +5,6 @@ PREP(handleVehicleDamage); PREP(handleCookoff); PREP(detonate); PREP(processHit); -PREP(injureOccupants); PREP(handleDetonation); PREP(handleDamage); PREP(knockOut); diff --git a/addons/vehicle_damage/functions/fnc_injureOccupants.sqf b/addons/vehicle_damage/functions/fnc_injureOccupants.sqf deleted file mode 100644 index 172d00e77a5..00000000000 --- a/addons/vehicle_damage/functions/fnc_injureOccupants.sqf +++ /dev/null @@ -1,76 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Injures occupants in a vehicle based on percent chance of injury. - * - * Arguments: - * 0: The vehicle - * 1: Injury Chance - * 2: Maximum people to injure - * 3: Projectile source (default: objNull) - * 4: Modifiers for probability for each crew type to be injured. (In order of: driver, gunner, commander, cargo) - * - * Return Value: - * None - * - * Example: - * [myVehicle, 0.6, 10] call ace_vehicle_damage_fnc_injureOccupants; - * - * Public: No - */ - -params ["_vehicle", "_chance", "_count", ["_source", objNull], ["_probabilityModifier", [1, 1, 1, 1]]]; -TRACE_4("adding damage to units", _vehicle, _chance, _count, _source); - -private _vehicleCrew = crew _vehicle; -private _crewCount = count _vehicleCrew; -if (_crewCount <= 0) exitWith {}; - -private _crewInjuryIndices = []; -{ - _crewInjuryIndices pushBack _forEachIndex; -} forEach _vehicleCrew; - -_crewInjuryIndices = _crewInjuryIndices call BIS_fnc_arrayShuffle; - -private _injuryCount = 0; -// Not actually doing anything to any initial vehicle crew in this forEach - just a way to loop through all crew at least once -{ - private _indexToInjure = -1; - { - private _modifier = _probabilityModifier select 3; - if ((_vehicleCrew select _x) isEqualTo driver _vehicle) then { - _modifier = _probabilityModifier select 0; - }; - if ((_vehicleCrew select _x) isEqualTo gunner _vehicle) then { - _modifier = _probabilityModifier select 1; - }; - if ((_vehicleCrew select _x) isEqualTo commander _vehicle) then { - _modifier = _probabilityModifier select 2; - }; - - if ((_chance * _modifier) > random 1) exitWith { - _indexToInjure = _forEachIndex; - }; - } forEach _crewInjuryIndices; - - if (_indexToInjure >= 0) then { - private _casualty = _vehicleCrew select (_crewInjuryIndices select _indexToInjure); - if (alive _casualty) then { - _injuryCount = _injuryCount + 1; - private _indexCount = count _crewInjuryIndices; - if (_indexCount >= 0) then { - _crewInjuryIndices deleteAt _indexToInjure; - - // arbitrary percentages - private _injuredBodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.3, 0.8, 0.5, 0.5, 0.3, 0.3]; - private _currentUnitDamage = _casualty getHitpointDamage _injuredBodyPart; - private _damageAmount = (_currentUnitDamage + random 1.8) max (_currentUnitDamage + 0.1); - - [_casualty, _damageAmount, _injuredBodyPart, "shell", _source] call EFUNC(medical,addDamageToUnit); - }; - }; - }; - - if (_injuryCount >= _count) exitWith {}; -} forEach _vehicleCrew; diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf index 3699fc1f5db..48d6ec00557 100644 --- a/addons/vehicle_damage/functions/fnc_processHit.sqf +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -119,28 +119,6 @@ if (_isCar) then { _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; }; -private _injuryChance = 0; -private _injuryCount = 0; -switch (_warheadType) do { - case WARHEAD_TYPE_AP: { - _injuryChance = (_ammoEffectiveness * 2) min 1; - _injuryCount = 1 + (_ammoEffectiveness * round random 9); - }; - case WARHEAD_TYPE_HE: { - _injuryChance = 0.03 * (1 + _ammoEffectiveness); // spalling injury chance alongside direct hit potential - _injuryCount = 2 + (ceil random 3); - if (_isCar) then { - _injuryChance = 0.8; - _injuryCount = 3 max random count crew _vehicle; - }; - }; - default { - _injuryChance = (4 * _ammoEffectiveness) min 1; - _injuryCount = 2 + round random 3; - }; -}; -_injuryChance = _injuryChance * _penChance; - private _currentVehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); private _chanceOfDetonation = 0; private _explosiveAmmoCount = 0; @@ -200,8 +178,6 @@ switch (_hitArea) do { [_vehicle, _hitIndex, _hitpointName, _nextPartDamage * _penChance] call FUNC(addDamage); }; - // slightly lower injury chance since this hit the engine block - [_vehicle, _injuryChance, _injuryCount, _injurer, [0.2, 0.2, 0.2, 0.4]] call FUNC(injureOccupants); [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, _hitArea, false] call FUNC(handleCookoff); }; case "hull": { @@ -220,8 +196,6 @@ switch (_hitArea) do { [_vehicle] call FUNC(knockOut); }; - [_vehicle, _injuryChance, _injuryCount, _injurer, [1, 0.4, 0.4, 1]] call FUNC(injureOccupants); - private _hash = _vehicle getVariable [QGVAR(hitpointHash), []]; private _hashKeys = [_hash] call CBA_fnc_hashKeys; @@ -301,7 +275,6 @@ switch (_hitArea) do { _vehicle setVariable [QGVAR(canShoot), false]; }; - [_vehicle, _injuryChance, _injuryCount, _injurer, [0.5, 1.5, 1.5, 0.8]] call FUNC(injureOccupants); [_vehicle, _chanceOfFire, _cookoffIntensity, _injurer, "", true] call FUNC(handleCookoff); }; case "gun": { From 661768b065603a89c9a52854acac0f93094d98ed Mon Sep 17 00:00:00 2001 From: LinkIsGrim Date: Sat, 23 Sep 2023 16:41:03 -0400 Subject: [PATCH 30/30] get rid of aircraft crash lethality compensation --- addons/medical_engine/XEH_postInit.sqf | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 64f8bab83b7..6455904f95e 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -61,20 +61,6 @@ }; }] call CBA_fnc_addClassEventHandler; -// Guarantee aircraft crashes are more lethal -["Air", "Killed", { - params ["_vehicle", "_killer"]; - TRACE_3("air killed",_vehicle,typeOf _vehicle,velocity _vehicle); - if ((getText (configOf _vehicle >> "destrType")) == "") exitWith {}; - if (unitIsUAV _vehicle) exitWith {}; - - private _lethality = linearConversion [0, 25, (vectorMagnitude velocity _vehicle), 0.5, 1]; - TRACE_2("air crash",_lethality,crew _vehicle); - { - [QEGVAR(medical,woundReceived), [_x, [[_lethality, "Head", _lethality]], _killer, "#vehiclecrash"], _x] call CBA_fnc_targetEvent; - } forEach (crew _vehicle); -}, true, ["ParachuteBase"]] call CBA_fnc_addClassEventHandler; - // Fixes units being stuck in unconscious animation when being knocked over by a PhysX object ["CAManBase", "AnimDone", { params ["_unit", "_anim"];