Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Medical Damage - Add alternate armor penetration #9217

Open
wants to merge 72 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
75f1cec
scale armor damage using passthrough
LinkIsGrim Jun 13, 2023
386eda6
add - to comment
LinkIsGrim Jun 14, 2023
510e6aa
improve condition
LinkIsGrim Jun 14, 2023
f290e28
remove extra brackets
LinkIsGrim Jun 14, 2023
9ad380d
remove extra brackets
LinkIsGrim Jun 14, 2023
0c82347
fix damage sorting
LinkIsGrim Jun 14, 2023
27ef26f
whitespace
LinkIsGrim Jun 14, 2023
0098ecb
comment
LinkIsGrim Jun 14, 2023
816c5e7
rework armor penetration
LinkIsGrim Jun 14, 2023
c232f7f
fix function header
LinkIsGrim Jun 14, 2023
92d636d
fix function header
LinkIsGrim Jun 14, 2023
33c3e9e
rework armor penetration
LinkIsGrim Jun 14, 2023
628c0c8
fix function header
LinkIsGrim Jun 14, 2023
7ad1d05
Merge branch 'rework-armor-penetration' of https://github.com/Salluci…
LinkIsGrim Jun 14, 2023
6991e8c
fix another function header
LinkIsGrim Jun 14, 2023
2d36e66
fix infinite armor when no item equipped
LinkIsGrim Jun 14, 2023
56ef3a3
remove extra return
LinkIsGrim Jun 14, 2023
cdf6520
fix infinite armor when no item equipped
LinkIsGrim Jun 14, 2023
1d1edbb
add private
LinkIsGrim Jun 14, 2023
73119fd
use math
LinkIsGrim Jun 15, 2023
8ef0af1
improve condition check
LinkIsGrim Jun 15, 2023
6035088
do it properly
LinkIsGrim Jun 15, 2023
434d5d5
improve macro, condition, remove unarmored bonus
LinkIsGrim Jun 16, 2023
dc39995
rework math again
LinkIsGrim Jun 17, 2023
34a4b24
cleanup
LinkIsGrim Jun 28, 2023
2b32870
more cleanup
LinkIsGrim Jun 28, 2023
aafef61
name
LinkIsGrim Jul 6, 2023
260e1c3
don't scale structural damage
LinkIsGrim Jul 9, 2023
e19bed4
Merge remote-tracking branch 'upstream' into rework-armor-penetration
LinkIsGrim Jul 24, 2023
2ed1058
Merge branch 'scale-armor-damage' of https://github.com/Salluci/ACE3 …
LinkIsGrim Jul 24, 2023
7b437b2
move to medical_damage component
LinkIsGrim Jul 24, 2023
82f1e41
revert changes to thresholds
LinkIsGrim Jul 24, 2023
60f0d77
fix stupid
LinkIsGrim Jul 24, 2023
6547fa0
finish moving to damage
LinkIsGrim Jul 24, 2023
0567367
fix double stupid
LinkIsGrim Jul 24, 2023
b77eca6
magic number
LinkIsGrim Jul 24, 2023
255ec5d
remove debug
LinkIsGrim Jul 24, 2023
6f706fe
remove debug pt2
LinkIsGrim Jul 24, 2023
e4e9345
final cleanup
LinkIsGrim Jul 24, 2023
ed9d6d6
did i say final? i meant pre-final.
LinkIsGrim Jul 24, 2023
46e21e9
remove 9216
LinkIsGrim Jul 24, 2023
bb53055
condition
LinkIsGrim Jul 25, 2023
d27f6f7
add default to ammo
LinkIsGrim Jul 28, 2023
97cdaf9
cleanup
LinkIsGrim Jul 28, 2023
383dda1
Merge branch 'rework-armor-penetration' of https://github.com/Salluci…
LinkIsGrim Jul 28, 2023
f1d5b80
remove debug
LinkIsGrim Jul 28, 2023
785502b
Merge remote-tracking branch 'upstream/master' into rework-armor-pene…
LinkIsGrim Aug 7, 2023
300d5fe
rework again (this time using armor class)
LinkIsGrim Aug 7, 2023
d227414
change default thickness
LinkIsGrim Aug 7, 2023
7e1821a
minor optimization, divide thickness by 2
LinkIsGrim Aug 7, 2023
540e479
fix missing bracket
LinkIsGrim Aug 7, 2023
84934a8
Merge branch 'master' of https://github.com/acemod/ACE3 into pr/LinkI…
LinkIsGrim Nov 16, 2024
6a449ca
fix script_component.hpp
LinkIsGrim Nov 16, 2024
5c09916
Fix macro
johnb432 Nov 17, 2024
5eba4c9
Use getOrDefaultCall
johnb432 Nov 17, 2024
d259ad1
Update docs
johnb432 Nov 17, 2024
d6cc11b
Update addons/medical_damage/functions/fnc_woundsHandlerArmorPenetrat…
LinkIsGrim Nov 17, 2024
a7eca55
Update addons/medical_damage/functions/fnc_getAmmoData.sqf
LinkIsGrim Nov 17, 2024
e29afd9
readd ammo if it was dropped
LinkIsGrim Nov 17, 2024
318f4b1
Merge branch 'master' into rework-armor-penetration
LinkIsGrim Nov 21, 2024
ef8d10d
Merge remote-tracking branch 'origin' into pr/LinkIsGrim/9217
LinkIsGrim Dec 19, 2024
26b3759
use scaling for stupid armor and nothing else, drop setting
LinkIsGrim Dec 19, 2024
54c9cb9
simplify armor thickness
LinkIsGrim Dec 19, 2024
18dc75d
no fun if it works the first time
LinkIsGrim Dec 19, 2024
2009431
fix undefined variable
LinkIsGrim Dec 19, 2024
ef0cdf7
fix logic
LinkIsGrim Dec 19, 2024
3fe5924
defer woundReceived changes to another PR
LinkIsGrim Dec 19, 2024
d566238
setting name/description
LinkIsGrim Dec 19, 2024
261c0a6
ammo fixes
LinkIsGrim Dec 19, 2024
7317266
drop doc change
LinkIsGrim Dec 19, 2024
a503f54
whitespace
LinkIsGrim Dec 19, 2024
833578e
round instead of floor to prevent floating point miscalc
LinkIsGrim Dec 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions addons/medical_damage/ACE_Medical_Injuries.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ class ACE_Medical_Injuries {
// bullets only create multiple wounds when the damage is very high
thresholds[] = {{20, 10}, {4.5, 2}, {3, 1}, {0, 1}};
selectionSpecific = 1;
class woundHandlers: woundHandlers {
GVAR(armorPenetration) = QFUNC(woundsHandlerArmorPenetration);
};

class Avulsion {
// at damage, weight. between points, weight is interpolated then wound is chosen by weighted random.
Expand Down
2 changes: 2 additions & 0 deletions addons/medical_damage/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
PREP(debug_explosiveTest);
PREP(determineIfFatal);
PREP(getAmmoData);
PREP(getTypeOfDamage);
PREP(handleIncapacitation);
PREP(interpolatePoints);
PREP(parseConfigForInjuries);
PREP(parseWoundHandlersCfg);
PREP(woundReceived);
PREP(woundsHandlerArmorPenetration);
PREP(woundsHandlerBase);
PREP(woundsHandlerBurning);
PREP(woundsHandlerVehiclecrash);
Expand Down
3 changes: 3 additions & 0 deletions addons/medical_damage/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ PREP_RECOMPILE_END;

call FUNC(parseConfigForInjuries);

// Used for armor penetration calculation
GVAR(ammoCache) = createHashMap;

/*
addMissionEventHandler ["Loaded",{
INFO("Mission Loaded - Reloading medical configs for extension");
Expand Down
30 changes: 30 additions & 0 deletions addons/medical_damage/functions/fnc_getAmmoData.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "..\script_component.hpp"
/*
* Author: LinkIsGrim
* Returns base damage value, penetration factor, and expected muzzle velocity of a given round, either from a cache or by reading the ammo config.
*
* Arguments:
* 0: Ammo <STRING>
*
* Return Value:
* Base damage value, penetration factor, muzzle velocity <ARRAY of NUMBER>
*
* Example:
* ["B_556x45_Ball"] call ace_medical_engine_fnc_getAmmoData
*
* Public: No
*/
// Baseline penetrability used for armor penetration calculation, see (https://community.bistudio.com/wiki/CfgAmmo_Config_Reference#caliber)
#define ARMOR_PENETRABILITY 0.015
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be a setting? /shrug.


params ["_ammo"];

GVAR(ammoCache) getOrDefaultCall [_ammo, {
TRACE_1("Cache miss",_ammo);
private _ammoConfig = configFile >> "CfgAmmo" >> _ammo;
private _hit = getNumber (_ammoConfig >> "hit");
private _caliber = (getNumber (_ammoConfig >> "caliber"));
private _typicalSpeed = getNumber (_ammoConfig >> "typicalSpeed");
private _penFactor = _caliber * ARMOR_PENETRABILITY;
[_hit, _penFactor, _typicalSpeed] // return
}, true] // return
LinkIsGrim marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 1 addition & 2 deletions addons/medical_damage/functions/fnc_woundReceived.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ private _typeOfDamage = _ammo call FUNC(getTypeOfDamage);
if (_typeOfDamage in GVAR(damageTypeDetails)) then {
(GVAR(damageTypeDetails) get _typeOfDamage) params ["", "", "_woundHandlers"];

private _damageData = [_unit, _allDamages, _typeOfDamage];

private _damageData = [_unit, _allDamages, _typeOfDamage, _ammo];
{
_damageData = _damageData call _x;
TRACE_1("Wound handler returned",_damageData);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#include "..\script_component.hpp"
/*
* Author: LinkIsGrim
* Custom wounds handler for armor penetration. Calculates damage based on round material penetration and unit armor
*
* Arguments:
* 0: Unit That Was Hit <OBJECT>
LinkIsGrim marked this conversation as resolved.
Show resolved Hide resolved
* 1: Damage done to each body part <ARRAY>
* 2: Type of the damage done <STRING>
* 3: Projectile classname <STRING> (default: "")
*
* Return Value:
* None
*
* Example:
* [player, [[0.5, "Body", 1]], "bullet"] call ace_medical_damage_fnc_woundsHandlerArmorPenetration
*
* Public: No
*/

// armor 2 with passthrough 0.8
#define SCALED_UNPROTECTED_VALUE 4
#define ENGINE_DAMAGE_INDEX 0

// This gets close to vanilla values on FMJ ammo
#define DAMAGE_SCALING_FACTOR 10

// Based off #9216 armor values for vanilla vests
#define ARMOR_LEVEL_1_CAP 12
#define ARMOR_LEVEL_2_CAP 14
#define ARMOR_LEVEL_3_CAP 16
#define ARMOR_LEVEL_4_CAP 20

params ["_unit", "_allDamages", "_typeOfDamage", ["_ammo", ""]];
TRACE_3("woundsHandlerArmorPenetration",_unit,_allDamages,_typeOfDamage);

if !(EGVAR(medical,alternateArmorPenetration) && {_ammo isNotEqualTo ""}) exitWith {_this};

private _damageData = (_allDamages select 0); // selection specific
_damageData params ["_engineDamage", "", "_realDamage"];

private _armor = (_realDamage/_engineDamage) - SCALED_UNPROTECTED_VALUE;
// There's no need to calculate penetration if there is no armor to begin with, vanilla damage handling is good enough in this case
if (_armor <= 0) exitWith {
_this // return
};

// Armor RHA equivalent, non-linear, ref \a3\Data_F\Penetration\armour_plate/thin/medium/heavy.bisurf
// Divided by 2 to keep inline with vanilla caliber values
// Excedent armor over the cap gets added as a small bonus to thickness
private _armorThickness = _armor/2;
switch (true) do {
case (_armor >= ARMOR_LEVEL_4_CAP): {
_armorThickness = 55 - (ARMOR_LEVEL_4_CAP - _armor);
};
case (_armor >= ARMOR_LEVEL_3_CAP): {
_armorThickness = 40 - (ARMOR_LEVEL_3_CAP - _armor);
};
case (_armor >= ARMOR_LEVEL_2_CAP): {
_armorThickness = 15 - (ARMOR_LEVEL_2_CAP - _armor);
};
case (_armor >= ARMOR_LEVEL_1_CAP): {
_armorThickness = 6 - (ARMOR_LEVEL_1_CAP - _armor);
};
};

// See (https://community.bistudio.com/wiki/CfgAmmo_Config_Reference#caliber),
// _penFactor is ammo "caliber" * RHA penetrability, armor plates according to BI are just made of RHA with different thickness
([_ammo] call FUNC(getAmmoData)) params ["_hit", "_penFactor", "_typicalSpeed"];

// Impact damage is hit * (impactSpeed / typicalSpeed): https://community.bistudio.com/wiki/CfgAmmo_Config_Reference#typicalSpeed
// Impact damage is already lowered by engine based on hit angle, so speed and therefore penetration are also naturally lowered
private _impactSpeed = (_realDamage/_hit) * _typicalSpeed;

private _penDepth = _penFactor * _impactSpeed;

// We want to base damage on the round's energy and armor penetration exclusively, so we'll use the config value to get damage
// There's only so much damage a round can do, limited by its energy
private _finalDamage = (_hit * ((_penDepth/_armorThickness) min 1)) / DAMAGE_SCALING_FACTOR;
_damageData set [ENGINE_DAMAGE_INDEX, _finalDamage];

TRACE_3("Armor penetration handled, passing damage",_finalDamage,_damageData,_allDamages);

_this // return
9 changes: 9 additions & 0 deletions addons/medical_damage/initSettings.inc.sqf
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
[
QEGVAR(medical,alternateArmorPenetration),
"CHECKBOX",
[LSTRING(AlternateArmorPenetration_DisplayName), LSTRING(AlternateArmorPenetration_Description)],
ELSTRING(medical,Category),
true,
true
] call CBA_fnc_addSetting;

[
QEGVAR(medical,fatalDamageSource),
"LIST",
Expand Down
6 changes: 6 additions & 0 deletions addons/medical_damage/stringtable.xml
Original file line number Diff line number Diff line change
Expand Up @@ -863,5 +863,11 @@
<Russian>Использовать урон конечностям</Russian>
<Japanese>手足のダメージを使用</Japanese>
</Key>
<Key ID="STR_ACE_Medical_Damage_AlternateArmorPenetration_DisplayName">
<English>Use Alternate Armor Penetration</English>
</Key>
<Key ID="STR_ACE_Medical_Damage_AlternateArmorPenetration_Description">
<English>Controls whether ammo material penetration ("caliber") is taken into account for damage handling.</English>
</Key>
</Package>
</Project>
1 change: 1 addition & 0 deletions docs/wiki/framework/medical-framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ Custom wound handlers should follow the same spec as the built-in handler:
| 0 | Unit that was hit | Object | Required |
| 1 | Array of damage dealt to each body part | Array | Required |
| 2 | Type of damage | String | Required |
| 3 | Ammo | String | Optional |
| **R** | Parameters to be passed to the next handler in the list, e.g. `_this` or a modified copy of it. Return `[]` to prevent further handling. | Array | Required |

The damage elements are sorted in descending order according to how much damage was dealt to each body part _before armor was taken into account_, but the actual damage values are _after armor_.
Expand Down