//#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