All pastes #2081965 Raw Edit

Stuff

public text v1 · immutable
#2081965 ·published 2011-09-21 22:23 UTC
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