ACE3/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf
jonpas 742626ff1a
General - Relative script_component.hpp includes (#9378)
Co-authored-by: PabstMirror <pabstmirror@gmail.com>
2023-09-12 20:58:10 +02:00

119 lines
4.5 KiB
Plaintext

#include "..\script_component.hpp"
/*
* Author: tcvm
* Calculates whether or not hit penetrated given armour or not. Only enabled with advanced penetration simulation turned on.
*
* Arguments:
* 0: Source of damage <OBJECT>
* 1: The vehicle <OBJECT>
* 2: Projectile that hit <OBJECT>
* 3: Hitpoint damaged <STRING>
*
* Return Value:
* None
*
* Example:
* [myVehicle, projectile, 5, 0.663] call ace_vehicle_damage_fnc_calculatePenetrationInfo;
*
* Public: No
*/
params ["_source", "_vehicle", "_projectileData", "_hitpointConfig"];
_projectileData params ["_projectileType", "_projectileConfig"];
/*
http://www.longrods.ch/peneq.php
https://www.scribd.com/doc/267210898/57-mm-APFSDS-2-000-m#download
Perforation Calculation of APFSDS:
Tungsten/Depleted Uranium: Rods
P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) * cos^m (theta) * sqrt (Pp / Pt) * e^((-(c0 + c1 * BHNT) * BHNT) / (Pp * Vt^2))
Steel Rods
P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) * cos^m (theta) * sqrt (Pp / Pt) * e^((-c * BHNT^k * BHNP^n) / (Pp * Vt^2))
Penetration Calculation of Tungsten APFSDS (Used for all penetrators):
P/Lw = a * (1 / tanh(b0 + b1 * (Lw/D))) sqrt (Pp / Pt) * e^((-(c0 + c1 * BHNT) * BHNT) / (Pp * Vt^2))
where:
Penetrator:
D = Diameter of penetrator rod (always 22mm)
L = Total length of penetrator in millimeters (always 950mm)
Lw = Working length of rod in millimeters
Vt = impact velocity in Kilometers/Second
theta = NATO Obliquity angle of Penetration
Pp = Penetrator Density in kg/m^3
BHNP = Brinell hardness number of penetrator
Target:
Pt = target density in kg/m^3 (always 7840kg/m^3)
d = plate thickness in millimeters
BHNT = Brinell hardness number of target (always 350)
Material Data:
Tungsten:
Pp = 19300
BHNP = N/A
a = 0.994
c0 = 134.5
c1 = -0.148
Depleted Uranium:
Pp = 18600
BHNP = N/A
a = 0.825
c0 = 90.0
c1 = -0.0849
Steel:
Pp = 7850
BHNP = 500
a = 1.104
c = 9874
k = 0.3598
n = -0.2342
Cofficients:
m = -0.224
b0 = 0.283
b1 = 0.0656
*/
private _enabled = ([_hitpointConfig >> QGVAR(enabled), "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1;
#define MATERIAL_ARRAY ([[0, 0, 0, 0, 0, 0], "steel", [7850, 500, 1.104, 9874, 0.3598, -0.2342], "tungsten", [19300, 0, 0.994, 134.5, -0.148], "depleted_uranium", [18600, 0, 0.825, 90, -0.0849]])
private _rodMaterialStr = [_projectileConfig >> QGVAR(material), "STRING", "tungsten"] call CBA_fnc_getConfigEntry;
private _rodMaterialParams = MATERIAL_ARRAY select (1 + MATERIAL_ARRAY find toLower _rodMaterial);
if !(_enabled) exitWith { [false, 0, 0, 0, 0] };
if (_rodMaterialParams isEqualTo [0, 0, 0, 0, 0, 0]) exitWith { [] };
private _tanX = 2 * (0.283 * 0.0656 * (1));
private _tanh = 1 / (((exp _tanX) - 1) / ((exp _tanX) + 1));
private _cosm = (cos 0) ^ -0.224;
private _lw = 950; // technically this would be something else depending on armour slant but this is a good enough aproximation
private _aproximateVelocity = 0;
private _perf_pLw = 0;
private _pen_pLw = 0;
if (_rodMaterialStr isEqualTo "steel") then {
_rodMaterialParams params ["_Pp", "_BHNP", "_a", "_c", "_k", "_n"];
private _exp = (-_c * 350^_k * _BHNP^_n) / (_Pp * _aproximateVelocity * _aproximateVelocity);
_pen_pLw = _a * _tanh * sqrt (_Pp / 7840) * exp _exp;
_perf_pLw = _pen_pLw * _cosm;
} else {
_rodMaterialParams params ["_Pp", "_BHNP", "_a", "_c0", "_c1"];
private _exp = (-(_c0 + _c1 * 350) * 350) / (_Pp * _aproximateVelocity * _aproximateVelocity);
_pen_pLw = _a * _tanh * _cosm * sqrt (_Pp / 7840) * exp _exp;
_perf_pLw = _pen_pLw * _cosm;
};
private _perforationDistance = _lw * _perf_pLw;
private _penetrationDistance = _lw * _pen_pLw;
private _hitpointEffectiveArmour = [_hitpointConfig >> QGVAR(thickness), "NUMBER", 0] call CBA_fnc_getConfigEntry;
private _hitpointEffectiveSlope = [_hitpointConfig >> QGVAR(slope), "NUMBER", 0] call CBA_fnc_getConfigEntry;
_penetrationDistance = _penetrationDistance * cos (_hitpointEffectiveSlope);
[_penetrationDistance > _hitpointEffectiveArmour, _penetrationDistance - _hitpointEffectiveArmour, _penetrationDistance, _perforationDistance, _hitpointEffectiveArmour]