rendered paste body//#define DEBUG_MODE_FULL
#include "script_component.hpp"
#define __unitcfg configFile >> "cfgVehicles" >> _unitType
#define __ammocfg configFile >> "cfgAmmo" >> _ammo
private ["_to", "_ammo", "_calls", "_firstCall", "_unit", "_allowDamage", "_isPlayer", "_sortedCalls", "_hitCall", "_part", "_partDamage", "_injurer", "_unitType", "_damage", "_armor", "_armorStruct", "_hit", "_typicalSpeed", "_configHit", "_velocity", "_direction", "_calibre", "_bloodLossConstant", "_mass", "_maxPenetraton", "_penetration", "_bloodLoss", "_ee", "_pd", "_ddam", "_bloss", "_isp"];
PARAMS_5(_unit,_part,_partdamage,_injurer,_ammo);
_unit setVariable [QUOTE(GVAR(handled)), true];
TRACE_1("hd2 start", "");
//_unit = _this;
//_calls = (_unit getVariable QUOTE(GVAR(hd)));
//_firstCall = _calls select 0;
//
_isPlayer = if (isPlayer _unit) then {true} else {false};
// if dead remove event handler
if (!alive _unit) exitwith {
if (!isNil {_unit getVariable QUOTE(GVAR(hdeh))}) then {
_unit removeEventHandler ["handleDamage", _unit getVariable QUOTE(GVAR(hdeh))];
};
};
// exit if damage is not allowed
_allowDamage = _unit getVariable QUOTE(GVAR(allow_dam));
if (!isNil "_allowDamage") exitWith {false};
// initialise unit if not initialised
_check = _unit getVariable QUOTE(GVAR(head_hit));
if (isNil "_check") then {_unit call FUNC(unitinit)};
_fsm = _unit getVariable QUOTE(GVAR(fsm));
if (isNil "_fsm") then {_fsm = 0};
if (_fsm == 0) then {
_unit setVariable [QUOTE(GVAR(fsm)),1];
[_unit] spawn FUNC(statehandler);
};
//
_part = _hitCall select 1;
_partdamage = _hitCall select 2;
_injurer = _hitCall select 3;
_ammo = _hitCall select 4;
//
_partId = -1;
_partMaxDepth = 180;
_partBloodLossMultiplier = 1;
switch (_part) do {
case "head_hit": { // head
_partId = 0;
_partMaxDepth = 180;
_partBloodLossMultiplier = 2;
};
case "body": { // body
_partId = 1;
_partMaxDepth = 300;
_partBloodLossMultiplier = 1;
};
case "hands": { // hands
_partId = 2;
_partMaxDepth = 100;
_partBloodLossMultiplier = 1;
};
case "legs": { // leg
_partId = 3;
_partMaxDepth = 160;
_partBloodLossMultiplier = 1;
};
};
_unitType = typeOf _unit;
// _damage - new damage received by unit (0..1)
_damage = _firstCall select 2;
// Finding current 'hit' value of projectile. Empiric formula.
_armor = getNumber (__unitcfg >> "armor");
_armorStruct = getNumber (__unitcfg >> "armorstructural");
_hit = 4.0235 * sqrt(_damage * _armor * _armorStruct);
// Calculating terminal velocity
_typicalSpeed = getNumber (__ammocfg >> "typicalSpeed");
_configHit = getNumber (__ammocfg >> "hit");
_velocity = _typicalSpeed * _hit / _configHit;
TRACE_5("wounds velocity",_velocity,_armor,_armorStruct,_hit,_configHit);
// calculate blood loss
_direction = [_unit, _injurer] call BIS_fnc_relativeDirTo;
_calibre = getNumber(__ammocfg >> "ace_calibre");
_bloodLossCoefficient = 0.0000001;
_mass = getNumber (__ammocfg >> "ace_mass");
_maxPenetraton = ((_velocity * _mass) / (_calibre^2)) * 5;
_penetration = _maxPenetraton min _partMaxDepth;
_bloodLoss = _penetration * 3.141592654 * _calibre * _bloodLossCoefficient;
// define vital areas
_vitals = [
[ // head
[0.4, 2], // brain
[0.05, 2], // spine
[0.1, 1, 2] // artery
],
[ // body
[0.05, 2], // spine
[0.02, 1, 15], // heart
[0.05, 1, 2] // artery
],
[ // hands
[0.05, 1, 2] // artery
],
[ // legs
[0.05, 1, 2] // artery
]
];
// get vital areas for current part
_partVitals = _vitals select _partId;
// loop through each vital, applying the effects if hit
{
_vital = _x;
_chance = _vital select 0;
_chance = _chance ^ (1 / ((_calibre ^ 0.5) * 2.35));
_random = (random 1);
if (_random <= _chance) then {
_effectType = _vital select 1;
switch (_effectType) do {
TRACE_1("vital hit", _vital);
case 1: { // increased bleed
_multiplier = _vital select 2;
_bloodLoss = _bloodLoss * _multiplier;
};
case 2: { // fatal
_unit setDamage 1;
};
};
};
} foreach _partVitals;
// create wounds
_wounds = [];
if (_penetration >= _partMaxDepth) then { // exit wound
_wounds = [
[_partId, _bloodLoss / 2],
[_partId, _bloodLoss]
];
} else {
_wounds = [
[_partId, _bloodLoss]
];
};
_painCoefficient = 0.000001;
_shockCoefficient = 0.000001;
_pain = 0.5 * _mass * (_velocity ^ 2) * _painCoefficient;
_shock = 0.5 * _mass * (_velocity ^ 2) * _shockCoefficient;
TRACE_6("wounds blood loss", _calibre, _mass, _maxPenetraton, _penetration, _bloodLoss, _pain);
// add blood loss
[_unit, _wounds] call FUNC(addWounds);
// add pain
[_unit, _pain] call FUNC(addPain);
// hit effects
_flinchCoefficient = _velocity * _mass;
[_unit, _ammo, _flinchCoefficient] call FUNC(effect);
// return
_return = 0;
_return