Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // #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);
- TRACE_1("hd2 start", "");
- _unit = _this;
- _calls = (_unit getVariable "ace_w_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 "ace_w_allow_dam";
- if (!isNil "_allowDamage") exitWith {false};
- // initialise unit if not initialised
- _check = _unit getVariable "ace_w_head_hit";
- if (isNil "_check") then {_unit call FUNC(unitinit)};
- _fsm = _unit getVariable "ace_w_stateHandler";
- if (isNil "_fsm") then {_fsm = 0};
- if (_fsm == 0) then {
- _unit setVariable ["ace_w_fsm",1];
- [_unit] spawn FUNC(statehandler);
- };
- // create a new array sorted by damage
- _sortedCalls = [_calls, 2] call CBA_fnc_sortNestedArray;
- // find which part was hit
- _hitCall = _sortedCalls select ((count _sortedCalls) -1);
- if ((_hitCall select 1) == "") then { // first call, not a part
- _hitCall = _sortedCalls select ((count _sortedCalls) -2);
- };
- //
- _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 >> "caliber");
- _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, 10], // 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
- if (_penetration >= _maxDepth) 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);
- // set blood loss
- _unit setVariable ["ace_w_wounds", (_unit getVariable "ace_w_wounds") + _wounds];
- [_unit, _bloodLoss, 0, 0] call FUNC(vchange);
- _unit setVariable ["ace_w_state",800]; // state 800 = bleeding signs, pain
- // hit effects
- [_unit, _ammo] call FUNC(effect);
- // return
- _return = 0;
- _return
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement