ACE3/addons/advanced_ballistics/functions/fnc_handleFired.sqf
ulteq ed772ebeb7
Advanced Ballistics - Typo: 'log' -> 'ln' (#5818)
We need to use the natural logarithm here.
2017-11-25 17:45:09 +01:00

118 lines
6.0 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Author: Glowbal, Ruthberg
*
* Handles advanced ballistics for (BulletBase) projectiles. Called from the unified fired EH only for players.
*
* Arguments:
* None. Parameters inherited from EFUNC(common,firedEH)
*
* Return Value:
* None
*
* Example:
* [] call ace_advanced_ballistics_fnc_handleFired
*
* Public: No
*/
#include "script_component.hpp"
//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"];
TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret);
if (!(_ammo isKindOf "BulletBase")) exitWith {};
if (!alive _projectile) exitWith {};
if (_unit distance ACE_player > GVAR(simulationRadius)) exitWith {};
if (underwater _unit) exitWith {};
private _abort = GVAR(disabledInFullAutoMode) && {getNumber(configFile >> "CfgWeapons" >> _weapon >> _mode >> "autoFire") == 1};
if (!local _unit && {!_abort && !GVAR(simulateForEveryone)}) then {
// The shooter is non local -> abort unless we match an exception rule
_abort = !GVAR(simulateForGroupMembers) || {group ACE_player != group _unit};
if (_abort && GVAR(simulateForSnipers)) then {
if (currentWeapon _unit == primaryWeapon _unit && count primaryWeaponItems _unit > 2) then {
private _opticsName = (primaryWeaponItems _unit) select 2;
private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
_abort = _opticType != 2; // We only abort if the non local shooter is not a sniper
};
};
};
//if (!GVAR(vehicleGunnerEnabled) && !(_unit isKindOf "Man")) then { _abort = true; }; // We currently do not have firedEHs on vehicles
// Get Weapon and Ammo Configurations
private _AmmoCacheEntry = uiNamespace getVariable format[QGVAR(%1), _ammo];
if (isNil "_AmmoCacheEntry") then {
_AmmoCacheEntry = _ammo call FUNC(readAmmoDataFromConfig);
};
private _WeaponCacheEntry = uiNamespace getVariable format[QGVAR(%1), _weapon];
if (isNil "_WeaponCacheEntry") then {
_WeaponCacheEntry = _weapon call FUNC(readWeaponDataFromConfig);
};
_AmmoCacheEntry params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"];
_WeaponCacheEntry params ["_barrelTwist", "_twistDirection", "_barrelLength"];
private _temperature = nil; // We need the variable in this scope. So we need to init it here.
private _ammoCount = _unit ammo _muzzle;
private _bulletVelocity = velocity _projectile;
private _muzzleVelocity = vectorMagnitude _bulletVelocity;
if (GVAR(barrelLengthInfluenceEnabled)) then {
_muzzleVelocity = _muzzleVelocity + ([_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift));
};
if (GVAR(ammoTemperatureEnabled)) then {
_temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
_muzzleVelocity = _muzzleVelocity + ([_ammoTempMuzzleVelocityShifts, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift));
};
if (GVAR(muzzleVelocityVariationEnabled)) then {
private _time = round (CBA_missionTime / 2);
// Generate seed from publicly known values (via Cantor pairing function)
private _seed = 0.5 * (_time + _ammoCount) * (_time + _ammoCount + 1) + _ammoCount;
// Generate normally distributed random number (via BoxMuller transform)
private _z = sqrt(-2.0 * ln(0.00000001 max (-_seed random 1))) * cos(_seed random 360);
_muzzleVelocity = _muzzleVelocity * (_z * _muzzleVelocityVariationSD + 1);
};
_bulletVelocity = (vectorNormalized _bulletVelocity) vectorMultiply _muzzleVelocity;
_projectile setVelocity _bulletVelocity;
if (_abort) exitWith {
if (missionNamespace getVariable [QEGVAR(windDeflection,enabled), false]) then {
EGVAR(windDeflection,trackedBullets) pushBack [_projectile, getNumber(configFile >> "CfgAmmo" >> _ammo >> "airFriction")];
};
};
private _bulletTraceVisible = false;
if (GVAR(bulletTraceEnabled) && cameraView == "GUNNER") then {
if (currentWeapon ACE_player == binocular ACE_player) then {
_bulletTraceVisible = true;
} else {
if (currentWeapon ACE_player == primaryWeapon ACE_player && count primaryWeaponItems ACE_player > 2) then {
private _opticsName = (primaryWeaponItems ACE_player) select 2;
private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
_bulletTraceVisible = _opticType == 2;
};
};
};
private _stabilityFactor = 1.5;
if (_caliber * _bulletLength * _bulletMass * _barrelTwist > 0) then {
if (isNil "_temperature") then {
_temperature = ((getPosASL _unit) select 2) call EFUNC(weather,calculateTemperatureAtHeight);
};
private _barometricPressure = ((getPosASL _projectile) select 2) call EFUNC(weather,calculateBarometricPressure);
_stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor);
};
GVAR(currentbulletID) = (GVAR(currentbulletID) + 1) % 10000;
"ace_advanced_ballistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", GVAR(currentbulletID), _ammoCount, _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _transonicStabilityCoef, getPosASL _projectile, _bulletVelocity, EGVAR(common,mapLatitude), EGVAR(weather,currentTemperature), EGVAR(common,mapAltitude), EGVAR(weather,currentHumidity), EGVAR(weather,currentOvercast), CBA_missionTime toFixed 6];
GVAR(allBullets) pushBack [_projectile, _caliber, _bulletTraceVisible, GVAR(currentbulletID)];
if (isNil QGVAR(BulletPFH)) then {
GVAR(BulletPFH) = [FUNC(handleFirePFH), GVAR(simulationInterval), []] call CBA_fnc_addPerFrameHandler;
};