From 616ba40f9a420be84df685e7ac422b7b1dde9528 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 1 Feb 2026 11:41:11 +0100 Subject: [PATCH 1/4] AB minor code refactor --- .../advanced_ballistics/CfgEventHandlers.hpp | 1 - addons/advanced_ballistics/RscTitles.hpp | 75 ++++----- addons/advanced_ballistics/XEH_PREP.hpp | 1 - addons/advanced_ballistics/XEH_postInit.sqf | 12 +- ..._calculateAmmoTemperatureVelocityShift.sqf | 27 +-- .../fnc_calculateAtmosphericCorrection.sqf | 25 ++- ...fnc_calculateBarrelLengthVelocityShift.sqf | 46 +++-- .../functions/fnc_calculateRetardation.sqf | 18 +- .../fnc_calculateStabilityFactor.sqf | 27 ++- .../functions/fnc_diagnoseWeapons.sqf | 158 ++++++++++-------- .../functions/fnc_displayProtractor.sqf | 63 +++---- .../functions/fnc_handleFirePFH.sqf | 11 +- .../functions/fnc_handleFired.sqf | 72 ++++---- .../fnc_initializeTerrainExtension.sqf | 15 +- .../functions/fnc_readAmmoDataFromConfig.sqf | 104 +++++++----- .../fnc_readWeaponDataFromConfig.sqf | 25 ++- .../advanced_ballistics/initKeybinds.inc.sqf | 8 +- .../advanced_ballistics/initSettings.inc.sqf | 2 +- .../advanced_ballistics/script_component.hpp | 6 - 19 files changed, 367 insertions(+), 329 deletions(-) diff --git a/addons/advanced_ballistics/CfgEventHandlers.hpp b/addons/advanced_ballistics/CfgEventHandlers.hpp index 6c29240403a..f6503c2479b 100644 --- a/addons/advanced_ballistics/CfgEventHandlers.hpp +++ b/addons/advanced_ballistics/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/advanced_ballistics/RscTitles.hpp b/addons/advanced_ballistics/RscTitles.hpp index 8cf3b3b0348..670585b4857 100644 --- a/addons/advanced_ballistics/RscTitles.hpp +++ b/addons/advanced_ballistics/RscTitles.hpp @@ -1,54 +1,53 @@ class RscTitles { class RscTurretDial { - idd=-1; - onLoad="with uiNameSpace do { RscTurretDial = _this select 0 };"; - movingEnable=0; - duration=5; - fadeIn="false"; - fadeOut="false"; + idd = -1; + movingEnable = 0; + duration = 5; + fadeIn = "false"; + fadeOut = "false"; class controls { class RscTurretDial { - idc=132949; - type=0; - style=128; - font="TahomaB"; - colorBackground[]={0,0,0,0.8}; - colorText[]={1,1,1,1}; - x="SafeZoneX + 0.0025"; - y="SafeZoneY + 0.0025"; - w=0.10; - h=0.05; - sizeEx=0.03; - text=""; + idc = 132949; + type = 0; + style = 128; + font = "TahomaB"; + colorBackground[] = {0, 0, 0, 0.8}; + colorText[] = {1, 1, 1, 1}; + x = "SafeZoneX + 0.0025"; + y = "SafeZoneY + 0.0025"; + w = 0.10; + h = 0.05; + sizeEx = 0.03; + text = ""; }; }; }; class RscProtractor { - idd=-1; - onLoad="with uiNameSpace do { RscProtractor = _this select 0 };"; - movingEnable=0; - duration=60; - fadeIn="false"; - fadeOut="false"; + idd = -1; + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(rscProtractor),_this select 0)]); + movingEnable = 0; + duration = 60; + fadeIn = "false"; + fadeOut = "false"; class controls { class RscProtractorBase { - idc=132950; - type=0; - style=48; - font="TahomaB"; - colorBackground[]={0,0,0,0}; - colorText[]={1,1,1,1}; - x="SafeZoneX + 0.001"; - y="SafeZoneY + 0.001"; - w=0.2; - h=0.2*4/3; - size=0.034; - sizeEx=0.027; - text=""; + idc = 132950; + type = 0; + style = 48; + font = "TahomaB"; + colorBackground[] = {0, 0, 0, 0}; + colorText[] = {1, 1, 1, 1}; + x = "SafeZoneX + 0.001"; + y = "SafeZoneY + 0.001"; + w = 0.2; + h = 0.2*4/3; + size = 0.034; + sizeEx = 0.027; + text = ""; }; class RscProtractorMarker: RscProtractorBase { - idc=132951; + idc = 132951; }; }; }; diff --git a/addons/advanced_ballistics/XEH_PREP.hpp b/addons/advanced_ballistics/XEH_PREP.hpp index df2501467ff..620313c2fe7 100644 --- a/addons/advanced_ballistics/XEH_PREP.hpp +++ b/addons/advanced_ballistics/XEH_PREP.hpp @@ -1,4 +1,3 @@ - PREP(calculateAmmoTemperatureVelocityShift); PREP(calculateAtmosphericCorrection); PREP(calculateBarrelLengthVelocityShift); diff --git a/addons/advanced_ballistics/XEH_postInit.sqf b/addons/advanced_ballistics/XEH_postInit.sqf index 25545d02aa0..5b2b6c18ea7 100644 --- a/addons/advanced_ballistics/XEH_postInit.sqf +++ b/addons/advanced_ballistics/XEH_postInit.sqf @@ -1,28 +1,24 @@ #include "script_component.hpp" -#include "initKeybinds.inc.sqf" - -GVAR(Protractor) = false; -GVAR(ProtractorStart) = CBA_missionTime; +GVAR(protractor) = false; GVAR(allBullets) = createHashMap; -GVAR(currentGrid) = 0; if (!hasInterface) exitWith {}; #include "initKeybinds.inc.sqf" ["CBA_settingsInitialized", { - //If not enabled, dont't add PFEH + // If not enabled, dont't add PFH if (!GVAR(enabled)) exitWith {}; - //Run the terrain processor + // Run the terrain processor [] call FUNC(initializeTerrainExtension); // Register fire event handler ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; - // Register Perframe Handler + // Register PFH [LINKFUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf index 6bc5a82fa2a..10454ee9c77 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAmmoTemperatureVelocityShift.sqf @@ -1,18 +1,17 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Calculates the ammo temperature induced muzzle velocity shift + * Calculates the ammo temperature induced muzzle velocity shift. * * Arguments: - * 0: muzzle velocity shift lookup table - m/s - * 1: temperature - degrees celcius + * 0: Muzzle velocity shift lookup table - m/s + * 1: Temperature - °C * * Return Value: - * muzzle velocity shift - m/s + * Muzzle velocity shift - m/s * * Example: - * [[], 5] call ace_advanced_ballistics_fnc_calculateAmmoTemperatureVelocityShift + * [[-27.20, -26.44, -23.76, -21.00, -17.54, -13.10, -7.95, -1.62, 6.24, 15.48, 27.75], 5] call ace_advanced_ballistics_fnc_calculateAmmoTemperatureVelocityShift * * Public: No */ @@ -20,15 +19,21 @@ params ["_muzzleVelocityShiftTable", "_temperature"]; // Check if muzzleVelocityShiftTable is less than 11 Entrys -if ((count _muzzleVelocityShiftTable) < 11) exitWith {0}; +if (count _muzzleVelocityShiftTable < 11) exitWith { + 0 // return +}; + private _muzzleVelocityShiftTableUpperLimit = _muzzleVelocityShiftTable select 10; -if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith {0}; + +if (isNil "_muzzleVelocityShiftTableUpperLimit") exitWith { + 0 // return +}; // Find exact data index required for given temperature private _temperatureIndexFunction = 0 max ((_temperature + 15) / 5) min 10; // Lower and upper data index used for interpolation -private _temperatureIndexA = floor(_temperatureIndexFunction); -private _temperatureIndexB = ceil(_temperatureIndexFunction); +private _temperatureIndexA = floor _temperatureIndexFunction; +private _temperatureIndexB = ceil _temperatureIndexFunction; -linearConversion [_temperatureIndexA, _temperatureIndexB, _temperatureIndexFunction, _muzzleVelocityShiftTable select _temperatureIndexA, _muzzleVelocityShiftTable select _temperatureIndexB, true] // Return +linearConversion [_temperatureIndexA, _temperatureIndexB, _temperatureIndexFunction, _muzzleVelocityShiftTable select _temperatureIndexA, _muzzleVelocityShiftTable select _temperatureIndexB, true] // return diff --git a/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf b/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf index c8486d7040c..c5161b9900c 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateAtmosphericCorrection.sqf @@ -1,31 +1,26 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Calculates the atmospherically corrected ballistic coefficient + * Calculates the atmospherically corrected ballistic coefficient. * * Arguments: - * 0: ballistic coefficient - G1-G7 - * 1: temperature - degrees celcius - * 2: pressure - hPa - * 3: relativeHumidity - value between 0.0 and 1.0 - * 4: atmosphereModel - ICAO or ASM + * 0: Ballistic coefficient - G1-G7 + * 1: Temperature - °C + * 2: Pressure - hPa + * 3: Relative humidity - value between 0 and 1 + * 4: Atmospheric model - "ICAO" or "ASM" * * Return Value: - * corrected ballistic coefficient + * Corrected ballistic coefficient * * Example: - * [2, 5, 5, 0.5, "ASM"] call ace_advanced_ballistics_fnc_calculateAtmosphericCorrection + * [0.151, 5, 1013.25, 0.5, "ICAO"] call ace_advanced_ballistics_fnc_calculateAtmosphericCorrection * * Public: No */ -params ["_ballisticCoefficient", "_temperature"/*in C*/, "_pressure"/*in hPa*/, "_relativeHumidity"/*as ratio 0-1*/, "_atmosphereModel"/*"ICAO" or "ASM"*/]; +params ["_ballisticCoefficient", "_temperature", "_pressure", "_relativeHumidity", "_atmosphereModel"]; private _airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); -if (_atmosphereModel == "ICAO") then { - (STD_AIR_DENSITY_ICAO / _airDensity) * _ballisticCoefficient -} else { - (STD_AIR_DENSITY_ASM / _airDensity) * _ballisticCoefficient -}; +([STD_AIR_DENSITY_ASM, STD_AIR_DENSITY_ICAO] select (_atmosphereModel == "ICAO")) / _airDensity * _ballisticCoefficient // return diff --git a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf index 5cf4a3af72c..d1cf6147d15 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateBarrelLengthVelocityShift.sqf @@ -1,20 +1,19 @@ #include "..\script_component.hpp" /* * Author: Ruthberg, MikeMatrix, joko // Jonas - * - * Calculates the muzzle velocity shift caused by different barrel lengths + * Calculates the muzzle velocity shift caused by different barrel lengths. * * Arguments: - * 0: barrel length - mm - * 1: muzzle velocity lookup table - m/s - * 2: barrel length lookup table - mm - * 3: muzzle velocity - m/s + * 0: Barrel length - mm + * 1: Muzzle velocity lookup table - m/s + * 2: Barrel length lookup table - mm + * 3: Reference muzzle velocity - m/s * * Return Value: - * muzzle velocity shift - m/s + * Muzzle velocity shift - m/s * * Example: - * [5, [0,5], [0,5], 5] call ace_advanced_ballistics_fnc_calculateBarrelLengthVelocityShift + * [508, [624, 816, 832, 838], [190.5, 368.3, 457.2, 508.0], 0] call ace_advanced_ballistics_fnc_calculateBarrelLengthVelocityShift * * Public: No */ @@ -23,23 +22,36 @@ params ["_barrelLength", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleV TRACE_4("params",_barrelLength,_muzzleVelocityTable,_barrelLengthTable,_muzzleVelocity); // If barrel length is not defined, then there is no point in calculating muzzle velocity -if (_barrelLength == 0) exitWith { 0 }; +if (_barrelLength == 0) exitWith { + 0 // return +}; private _muzzleVelocityTableCount = count _muzzleVelocityTable; -private _barrelLengthTableCount = count _barrelLengthTable; // Exit if tables are different sizes, have no elements or have only one element -if (_muzzleVelocityTableCount != _barrelLengthTableCount || _muzzleVelocityTableCount == 0) exitWith { 0 }; -if (_muzzleVelocityTableCount == 1) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity }; +if (_muzzleVelocityTableCount != count _barrelLengthTable || _muzzleVelocityTableCount == 0) exitWith { + 0 // return +}; + +if (_muzzleVelocityTableCount == 1) exitWith { + (_muzzleVelocityTable select 0) - _muzzleVelocity // return +}; + +private _index = _barrelLengthTable find _barrelLength; // If we have the precise barrel length value, return result immediately -if (_barrelLength in _barrelLengthTable) exitWith { - (_muzzleVelocityTable select (_barrelLengthTable find _barrelLength)) - _muzzleVelocity +if (_index != -1) exitWith { + (_muzzleVelocityTable select _index) - _muzzleVelocity // return }; // Limit values to lower and upper bound of data we have available -if (_barrelLength <= (_barrelLengthTable select 0)) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity }; -if (_barrelLength >= (_barrelLengthTable select _barrelLengthTableCount - 1)) exitWith { (_muzzleVelocityTable select _barrelLengthTableCount - 1) - _muzzleVelocity }; +if (_barrelLength <= (_barrelLengthTable select 0)) exitWith { + (_muzzleVelocityTable select 0) - _muzzleVelocity // return +}; + +if (_barrelLength >= (_barrelLengthTable select -1)) exitWith { + (_muzzleVelocityTable select -1) - _muzzleVelocity // return +}; private _upperDataIndex = 0; private _lowerDataIndex = 1; @@ -52,4 +64,4 @@ private _lowerDataIndex = 1; }; } forEach _barrelLengthTable; -(linearConversion [_barrelLengthTable select _lowerDataIndex, _barrelLengthTable select _upperDataIndex, _barrelLength, _muzzleVelocityTable select _lowerDataIndex, _muzzleVelocityTable select _upperDataIndex]) - _muzzleVelocity // Return +(linearConversion [_barrelLengthTable select _lowerDataIndex, _barrelLengthTable select _upperDataIndex, _barrelLength, _muzzleVelocityTable select _lowerDataIndex, _muzzleVelocityTable select _upperDataIndex]) - _muzzleVelocity // return diff --git a/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf b/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf index ccd7363f9b7..5de8b77519c 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateRetardation.sqf @@ -1,19 +1,18 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Calculates the retardation of the bullet + * Calculates the retardation of the bullet. * * Arguments: - * 0: drag model - integer 1-7 - * 1: drag coefficient - bc - * 2: velocity - m/s + * 0: Drag model - integer 1-7 + * 1: Drag coefficient - bc + * 2: Velocity - m/s * * Return Value: - * retardation - m/(s^2) + * Retardation - m/(s^2) * * Example: - * [5, 20, 10] call ace_advanced_ballistics_fnc_calculateRetardation + * [7, 0.151, 878] call ace_advanced_ballistics_fnc_calculateRetardation * * Public: No */ @@ -22,6 +21,7 @@ private ["_A", "_M"]; params ["_dragModel", "_dragCoefficient", "_velocity"]; + _velocity = _velocity * 3.2808399; switch _dragModel do { @@ -129,7 +129,7 @@ switch _dragModel do { }; if (!isNil "_A" && !isNil "_M" && _velocity > 0 && _velocity < 10000) then { - (_A * (_velocity ^ _M) / _dragCoefficient) / 3.2808399 + (_A * (_velocity ^ _M) / _dragCoefficient) / 3.2808399 // return } else { - 0 + 0 // return }; diff --git a/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf b/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf index 2ee8ce3e3ac..0eeed169bc0 100644 --- a/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf +++ b/addons/advanced_ballistics/functions/fnc_calculateStabilityFactor.sqf @@ -1,23 +1,22 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Calculates the stability factor of a bullet + * Calculates the stability factor of a bullet. * * Arguments: - * 0: caliber - mm - * 1: bullet length - mm - * 2: bullet mass - grams - * 3: barrel twist - mm - * 4: muzzle velocity shift - m/s - * 5: temperature - degrees celcius - * 6: barometric Pressure - hPA + * 0: Caliber - mm + * 1: Bullet length - mm + * 2: Bullet mass - grams + * 3: Barrel twist - mm + * 4: Muzzle velocity shift - m/s + * 5: Temperature - °C + * 6: Barometric pressure - hPA * * Return Value: - * stability factor + * Stability factor * * Example: - * [1, 2, 3, 4, 5, 6, 7] call ace_advanced_ballistics_fnc_calculateStabilityFactor + * [6, 23, 4, 177.8, -23.76, 0, 1013.25] call ace_advanced_ballistics_fnc_calculateStabilityFactor * * Public: No */ @@ -30,8 +29,4 @@ private _length = _bulletLength / _caliber; private _stabilityFactor = 7587000 * _bulletMass / (_twist^2 * _caliber^3 * _length * (1 + _length^2)); -if (_muzzleVelocity > 341.376) then { - (_stabilityFactor * (_muzzleVelocity / 853.44) ^ (1/3)) * KELVIN(_temperature) / KELVIN(15) * 1013.25 / _barometricPressure -} else { - (_stabilityFactor * (_muzzleVelocity / 341.376) ^ (1/3)) * KELVIN(_temperature) / KELVIN(15) * 1013.25 / _barometricPressure -}; +(_stabilityFactor * (_muzzleVelocity / ([341.376, 853.44] select (_muzzleVelocity > 341.376))) ^ (1/3)) * KELVIN(_temperature) / KELVIN(15) * 1013.25 / _barometricPressure // return diff --git a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf index 699db035759..3448d3f7a24 100644 --- a/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf +++ b/addons/advanced_ballistics/functions/fnc_diagnoseWeapons.sqf @@ -1,12 +1,11 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * * This function diagnoses all primary weapons to find cases in which the initial - * velocity of shots with and without AB significantly mismatch + * velocity of shots with and without AB significantly mismatch. * * Arguments: - * None. Parameters inherited from EFUNC(common,firedEH) + * None * * Return Value: * None @@ -20,100 +19,119 @@ private _diagnoseStartTime = diag_tickTime; #ifdef DEBUG_INIT_SPEEDS private _data = []; - private _weapons = []; - private _magazines = []; - private _weaponInitSpeeds = []; - private _magazineInitSpeeds = []; #endif private _cfgWeapons = configFile >> "CfgWeapons"; -for "_i" from 0 to (count _cfgWeapons)-1 do { - private _weaponConfig = _cfgWeapons select _i; - if (isClass _weaponConfig) then { - private _weapon = configName _weaponConfig; - private _weaponType = getNumber (_weaponConfig >> "Type"); - if (_weaponType in [TYPE_WEAPON_PRIMARY, TYPE_WEAPON_HANDGUN]) then { - private _weaponInitSpeed = getNumber (_weaponConfig >> "initSpeed"); - private _magazines = getArray (_weaponConfig >> "magazines"); - { - private _magazine = _x; - private _magazineInitSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); - private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); - - // Vanilla initial speed -------------------------- - private _vanillaInitialSpeed = _magazineInitSpeed; - if (_weaponInitSpeed > 0) then { - _vanillaInitialSpeed = _weaponInitSpeed; - } else { - if (_weaponInitSpeed < 0) then { - _vanillaInitialSpeed = _vanillaInitialSpeed * (-_weaponInitSpeed); - }; - }; - // -------------------------------------------------- - - // AB initial speed -------------------------------- - // Get Weapon and Ammo Configurations - (_ammo call FUNC(readAmmoDataFromConfig)) params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; - (_weapon call FUNC(readWeaponDataFromConfig)) params ["_barrelTwist", "_twistDirection", "_barrelLength"]; - - private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _vanillaInitialSpeed] call FUNC(calculateBarrelLengthVelocityShift); - if (_barrelLength > 0) then { - private _shiftedMV = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call FUNC(calculateBarrelLengthVelocityShift); - if (_shiftedMV == 0) then { ERROR_2("%1:%2 has length set but invalid mags",_weapon,_magazine)}; - }; - private _abInitialSpeed = _vanillaInitialSpeed + _barrelVelocityShift; - // -------------------------------------------------- - - if (_weapon find "_base" == -1 && _weapon find "_Base" == -1) then { +private _cfgMagazines = configFile >> "CfgMagazines"; + +private _filterFunction = toString { + (getNumber (_x >> "type") in [TYPE_WEAPON_PRIMARY, TYPE_WEAPON_HANDGUN]) && + {configName _x == getText (_x >> "baseWeapon")} && + {if (isNumber (_x >> "scopeArsenal")) then {getNumber (_x >> "scopeArsenal") == 2 && {getNumber (_x >> "scope") > 0}} else {getNumber (_x >> "scope") == 2}} +}; + +{ + private _weaponConfig = _x; + private _weapon = configName _weaponConfig; + + private _weaponInitSpeed = getNumber (_weaponConfig >> "initSpeed"); + private _magazines = getNumber (_weaponConfig >> "magazines"); + private _magazines = compatibleMagazines [_weapon, "this"]; + + _magazines sort true; + + { + private _magazine = _x; + private _magazineConfig = _cfgMagazines >> _magazine; + private _magazineInitSpeed = getNumber (_magazineConfig >> "initSpeed"); + private _ammo = getText (_magazineConfig >> "ammo"); + + // AB initial speed -------------------------------- + // Get weapon and ammo configurations + (_ammo call FUNC(readAmmoDataFromConfig)) params ["_airFriction", "_caliber", "_bulletLength", "_bulletMass", "_transonicStabilityCoef", "_dragModel", "_ballisticCoefficients", "_velocityBoundaries", "_atmosphereModel", "_ammoTempMuzzleVelocityShifts", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocityVariationSD"]; + (_weapon call FUNC(readWeaponDataFromConfig)) params ["_barrelTwist", "_twistDirection", "_barrelLength"]; + + if (_barrelLength > 0) then { + private _shiftedMV = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call FUNC(calculateBarrelLengthVelocityShift); + + if (_shiftedMV == 0) then { + ERROR_2("%1:%2 has length set but invalid mags",_weapon,_magazine); + }; + }; + + // Vanilla initial speed -------------------------- + private _vanillaInitialSpeed = _magazineInitSpeed; + + if (_weaponInitSpeed > 0) then { + _vanillaInitialSpeed = _weaponInitSpeed; + } else { + if (_weaponInitSpeed < 0) then { + _vanillaInitialSpeed = _vanillaInitialSpeed * -_weaponInitSpeed; + }; + }; + + private _barrelVelocityShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, _vanillaInitialSpeed] call FUNC(calculateBarrelLengthVelocityShift); + private _abInitialSpeed = _vanillaInitialSpeed + _barrelVelocityShift; + #ifdef DEBUG_INIT_SPEEDS - _data pushBack [-_forEachIndex, _abInitialSpeed, _magazine, _weapon]; + _data pushBack [_abInitialSpeed, _magazine, _weapon]; #endif - if (_barrelLength > 0 && abs(_vanillaInitialSpeed - _abInitialSpeed) > abs(_abInitialSpeed) * 0.0025) then { - diag_log text format ["AB_Diagnose_initSpeed,%1,%2,%3,%4,%5,%6,%7,%8",_weapon,_magazine,_ammo,_magazineInitSpeed,_weaponInitSpeed,_vanillaInitialSpeed,_abInitialSpeed,_abInitialSpeed/_vanillaInitialSpeed]; - }; - if (_barrelTwist == 0) then { - diag_log text format ["AB_Diagnose_barrelTwist,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_twistDirection,_barrelTwist]; - }; - if (_barrelLength == 0) then { - diag_log text format ["AB_Diagnose_barrelLength,%1,%2,%3,%4",_weapon,_magazine,_ammo,_barrelLength]; - }; - }; - } forEach _magazines; + if (_barrelLength > 0 && abs (_vanillaInitialSpeed - _abInitialSpeed) > abs _abInitialSpeed * 0.0025) then { + diag_log text format ["AB_Diagnose_initSpeed,%1,%2,%3,%4,%5,%6,%7,%8",_weapon,_magazine,_ammo,_magazineInitSpeed,_weaponInitSpeed,_vanillaInitialSpeed,_abInitialSpeed,_abInitialSpeed/_vanillaInitialSpeed]; }; - }; -}; + + if (_barrelTwist == 0) then { + diag_log text format ["AB_Diagnose_barrelTwist,%1,%2,%3,%4,%5",_weapon,_magazine,_ammo,_twistDirection,_barrelTwist]; + }; + + if (_barrelLength == 0) then { + diag_log text format ["AB_Diagnose_barrelLength,%1,%2,%3,%4",_weapon,_magazine,_ammo,_barrelLength]; + }; + } forEach _magazines; +} forEach (_filterFunction configClasses _cfgWeapons); #ifdef DEBUG_INIT_SPEEDS - _data sort false; + private _weapons = createHashMap; + private _magazines = []; + private _magazineInitSpeeds = []; + + reverse _data; + { - _x params ["_magazineIndex", "_abInitialSpeed", "_magazine", "_weapon"]; - if (_magazines find _magazine == -1) then { + _x params ["_abInitialSpeed", "_magazine", "_weapon"]; + + if !(_magazine in _magazines) then { private _magSpeed = _abInitialSpeed; - private _ammoRef = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); + private _ammoRef = getText (_cfgMagazines >> _magazine >> "ammo"); + if (_ammoRef != "") then { { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + if (_ammo == _ammoRef) exitWith { _magSpeed = _magazineInitSpeeds select _forEachIndex; }; } forEach _magazines; }; + _magazines pushBack _magazine; - _magazineInitSpeeds pushBack round(_magSpeed); + _magazineInitSpeeds pushBack (round _magSpeed); }; - if (_weapons find _weapon == -1) then { - _weapons pushBack _weapon; + + if !(_weapon in _weapons) then { private _magIndex = _magazines find _magazine; private _magSpeed = _magazineInitSpeeds select _magIndex; - _weaponInitSpeeds pushBack (_abInitialSpeed / _magSpeed); + _weapons set [_weapon, _abInitialSpeed / _magSpeed]; }; } forEach _data; + { - diag_log text format ["AB_WeaponInitSpeed,%1,%2", _x, _weaponInitSpeeds select _forEachIndex]; + diag_log text format ["AB_WeaponInitSpeed,%1,%2", _x, _y]; } forEach _weapons; + { diag_log text format ["AB_MagazineInitSpeed,%1,%2", _x, _magazineInitSpeeds select _forEachIndex]; } forEach _magazines; #endif -diag_log format["AdvancedBallistics: Finished 'diagnoseWeapons' in %1 seconds", (diag_tickTime - _diagnoseStartTime) toFixed 2]; +diag_log format ["AdvancedBallistics: Finished 'diagnoseWeapons' in %1 seconds", (diag_tickTime - _diagnoseStartTime) toFixed 2]; diff --git a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf index f48715a5d36..753f52e2d16 100644 --- a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf +++ b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf @@ -1,14 +1,13 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Displays a protractor in the top left corner of the screen + * Displays a protractor in the top left corner of the screen. * * Arguments: * None * * Return Value: - * None + * If the key stroke was handled * * Example: * [] call ace_advanced_ballistics_fnc_displayProtractor @@ -16,45 +15,51 @@ * Public: No */ -#define __dsp (uiNamespace getVariable "RscProtractor") -#define __ctrl1 (__dsp displayCtrl 132950) -#define __ctrl2 (__dsp displayCtrl 132951) - -if (GVAR(Protractor)) exitWith { - GVAR(Protractor) = false; +if (GVAR(protractor)) exitWith { + GVAR(protractor) = false; 1 cutText ["", "PLAIN"]; - true + true // return +}; + +if (weaponLowered ACE_player || !isNull objectParent ACE_player || currentWeapon ACE_player != primaryWeapon ACE_player) exitWith { + false // return }; -if (weaponLowered ACE_player) exitWith { false }; -if (!isNull objectParent ACE_player) exitWith { false }; -if (currentWeapon ACE_player != primaryWeapon ACE_player) exitWith { false }; 2 cutText ["", "PLAIN"]; EGVAR(weather,WindInfo) = false; (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; -GVAR(Protractor) = true; +GVAR(protractor) = true; [{ - params ["","_idPFH"]; - if !(GVAR(Protractor) && !(weaponLowered ACE_player) && currentWeapon ACE_player == primaryWeapon ACE_player) exitWith { - GVAR(Protractor) = false; + disableSerialization; + + params ["", "_idPFH"]; + + private _currentWeapon = currentWeapon ACE_player; + + if (!GVAR(protractor) || weaponLowered ACE_player || _currentWeapon != primaryWeapon ACE_player) exitWith { + GVAR(protractor) = false; 1 cutText ["", "PLAIN"]; - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; 1 cutRsc ["RscProtractor", "PLAIN", 1, false]; - __ctrl1 ctrlSetScale 1; - __ctrl1 ctrlCommit 0; - __ctrl1 ctrlSetText QPATHTOF(UI\protractor.paa); - __ctrl1 ctrlSetTextColor [1, 1, 1, 1]; + private _display = uiNamespace getVariable QGVAR(rscProtractor); + private _ctrl1 = _display displayCtrl 132950; + + _ctrl1 ctrlSetScale 1; + _ctrl1 ctrlCommit 0; + _ctrl1 ctrlSetText QPATHTOF(UI\protractor.paa); + _ctrl1 ctrlSetTextColor [1, 1, 1, 1]; - __ctrl2 ctrlSetScale 1; - __ctrl2 ctrlSetPosition [safeZoneX + 0.001, safeZoneY - 0.001 - 0.1074 * (-0.86 max ((ACE_player weaponDirection currentWeapon ACE_player) select 2) min 0.86), 0.2, 0.2 * 4/3]; - __ctrl2 ctrlCommit 0; - __ctrl2 ctrlSetText QPATHTOF(UI\protractor_marker.paa); - __ctrl2 ctrlSetTextColor [1, 1, 1, 1]; + private _ctrl2 = _display displayCtrl 132951; -}, 0.1, []] call CBA_fnc_addPerFrameHandler; + _ctrl2 ctrlSetScale 1; + _ctrl2 ctrlSetPosition [safeZoneX + 0.001, safeZoneY - 0.001 - 0.1074 * (-0.86 max ((ACE_player weaponDirection _currentWeapon) select 2) min 0.86), 0.2, 0.2 * 4/3]; + _ctrl2 ctrlCommit 0; + _ctrl2 ctrlSetText QPATHTOF(UI\protractor_marker.paa); + _ctrl2 ctrlSetTextColor [1, 1, 1, 1]; +}, 0.1] call CBA_fnc_addPerFrameHandler; -true +true // return diff --git a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf index 9e1a485f21f..1ccc228b023 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFirePFH.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg, joko // Jonas, Brett Mayson - * Handle the PFH for Bullets + * Handle the PFH for Bullets. * * Arguments: * None @@ -16,7 +16,7 @@ */ { - _y params ["_bullet","_caliber","_bulletTraceVisible"]; + _y params ["_bullet", "_caliber", "_bulletTraceVisible"]; if (alive _bullet) then { private _bulletVelocity = velocity _bullet; @@ -32,15 +32,16 @@ _bulletVelocity, _bulletPosition, wind, - ASLToATL(_bulletPosition) select 2, + (ASLToATL _bulletPosition) select 2, CBA_missionTime toFixed 6 ]] ) params ["_data", "_code"]; + if (_code == 0) then { - _bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray (_data))); + _bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray _data)); }; } else { GVAR(allBullets) deleteAt _x; "ace" callExtension ["ballistics:bullet:delete", [_x]]; }; -} forEach GVAR(allBullets) +} forEach GVAR(allBullets); diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index 7b59e3229e6..3523458e025 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -1,7 +1,6 @@ #include "..\script_component.hpp" /* * Author: Glowbal, Ruthberg, Brett Mayson - * * Handles advanced ballistics for (BulletBase) projectiles. Called from the unified fired EH only for players. * * Arguments: @@ -23,21 +22,22 @@ if !(_ammo isKindOf "BulletBase") exitWith {}; if (!alive _projectile) exitWith {}; if (underwater _unit) exitWith {}; +private _bulletVelocity = velocity _projectile; +private _muzzleVelocity = vectorMagnitude _bulletVelocity; private _abort = !local _unit; -if (_abort) then { - private _bulletVelocity = velocity _projectile; - private _muzzleVelocity = vectorMagnitude _bulletVelocity; +// Estimate if a bullet from a remote unite needs to be accurately simulated +if (_abort) then { private _maxRange = GVAR(maxRange) getOrDefaultCall [_ammo, { private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; - private _airFriction = getNumber(_ammoConfig >> "airFriction"); + private _airFriction = getNumber (_ammoConfig >> "airFriction"); private _vanillaInitialSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); private _maxRange = if (_airFriction < 0) then { - private _maxTime = ((_vanillaInitialSpeed - BULLET_TRACE_MIN_VELOCITY) / (BULLET_TRACE_MIN_VELOCITY * -_airFriction * _vanillaInitialSpeed)) max getNumber(_ammoConfig >> "tracerEndTime"); - -ln(1 - _airFriction * _vanillaInitialSpeed * _maxTime) / _airFriction + private _maxTime = ((_vanillaInitialSpeed - BULLET_TRACE_MIN_VELOCITY) / (BULLET_TRACE_MIN_VELOCITY * -_airFriction * _vanillaInitialSpeed)) max getNumber (_ammoConfig >> "tracerEndTime"); + -ln (1 - _airFriction * _vanillaInitialSpeed * _maxTime) / _airFriction } else { - _vanillaInitialSpeed * getNumber(_ammoConfig >> "tracerEndTime") + _vanillaInitialSpeed * getNumber (_ammoConfig >> "tracerEndTime") }; _maxRange * 1.3 // Adding 30% more to range just to be safe @@ -45,17 +45,32 @@ if (_abort) then { if (ACE_player distance _unit > _maxRange && {ACE_player distance ((getPosASL _unit) vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply _maxRange)) > _maxRange}) exitWith {}; - if (_projectile getShotInfo 4) exitWith { _abort = false }; // 4=shownTracer + // If the bullet is a tracer bullet, it needs to be accurately simulated + _abort = !(_projectile getShotInfo 4); // 4=shownTracer +}; + +private _bulletTraceVisible = false; - if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then { - if (currentWeapon ACE_player == binocular ACE_player) exitWith { _abort = false }; - if (currentWeapon ACE_player == primaryWeapon ACE_player) then { - private _opticsName = (primaryWeaponItems ACE_player) select 2; - private _opticType = getNumber(configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType"); - if (_opticType == 2) exitWith { _abort = false }; +// If the bullet can be observed accurately, then simulate the bullet accurately as well +if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then { + private _currentWeapon = currentWeapon ACE_player; + + if (_currentWeapon == binocular ACE_player) exitWith { + _bulletTraceVisible = true; + _abort = false; + }; + + if (_currentWeapon == primaryWeapon ACE_player) then { + private _opticsName = (primaryWeaponItems ACE_player) select 2; + private _opticType = getNumber (configFile >> "CfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType"); + + if (_opticType == 2) then { + _bulletTraceVisible = true; + _abort = false; }; }; }; + if (_abort) exitWith {}; // Get Weapon and Ammo Configurations @@ -63,24 +78,23 @@ if (_abort) exitWith {}; ([_weapon, _muzzle] call FUNC(readWeaponDataFromConfig)) 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 Box–Muller transform) - private _z = sqrt(-2.0 * ln(0.00000001 max (-_seed random 1))) * cos(_seed random 360); + private _z = sqrt (-2.0 * ln (0.00000001 max (-_seed random 1))) * cos (_seed random 360); _muzzleVelocity = _muzzleVelocity * (_z * _muzzleVelocityVariationSD + 1); }; @@ -88,26 +102,15 @@ if (GVAR(muzzleVelocityVariationEnabled)) then { _bulletVelocity = (vectorNormalized _bulletVelocity) vectorMultiply _muzzleVelocity; _projectile setVelocity _bulletVelocity; -private _bulletTraceVisible = false; -if (GVAR(bulletTraceEnabled) && {_muzzleVelocity > BULLET_TRACE_MIN_VELOCITY} && {cameraView == "GUNNER"}) then { - if (currentWeapon ACE_player == binocular ACE_player) then { - _bulletTraceVisible = true; - } else { - if (currentWeapon ACE_player == primaryWeapon ACE_player) 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 { +private _stabilityFactor = 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); +} else { + 1.5 }; ("ace" callExtension [ @@ -130,6 +133,7 @@ if (_caliber * _bulletLength * _bulletMass * _barrelTwist > 0) then { CBA_missionTime toFixed 6 ] ]) params ["_id", "_code"]; + if (_code == 0) then { GVAR(allBullets) set [_id, [_projectile, _caliber, _bulletTraceVisible]]; }; diff --git a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf index 8ad90981ffb..2234973ebaf 100644 --- a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf +++ b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf @@ -21,9 +21,8 @@ if (!GVAR(enabled)) exitWith {}; private _initStartTime = diag_tickTime; private _mapSize = worldSize; -( - "ace" callExtension ["ballistics:map:init", [worldName, _mapSize]] -) params ["_data", "_code"]; +("ace" callExtension ["ballistics:map:init", [worldName, _mapSize]]) params ["_data", "_code"]; + if (_code != 0) exitWith { ERROR("Error initializing map") }; @@ -35,7 +34,7 @@ if (_data == "true") exitWith { #endif }; -private _mapGrids = ceil(_mapSize / 50) + 1; +private _mapGrids = ceil (_mapSize / 50) + 1; private _gridCells = _mapGrids * _mapGrids; GVAR(currentGrid) = 0; @@ -49,14 +48,14 @@ INFO_2("Starting Terrain Extension [cells: %1] [world: %2]",_gridCells,worldName if (GVAR(currentGrid) >= _gridCells) exitWith { INFO_2("Finished terrain initialization in %1 seconds [world: %2]",(diag_tickTime - _initStartTime) toFixed 2,worldName); #ifdef DEBUG_MODE_FULL - systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2]; + systemChat format ["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2]; #endif - [_idPFH] call CBA_fnc_removePerFrameHandler; + _idPFH call CBA_fnc_removePerFrameHandler; }; for "_i" from 1 to 50 do { - private _x = floor(GVAR(currentGrid) / _mapGrids) * 50; - private _y = (GVAR(currentGrid) - floor(GVAR(currentGrid) / _mapGrids) * _mapGrids) * 50; + private _x = floor (GVAR(currentGrid) / _mapGrids) * 50; + private _y = (GVAR(currentGrid) - floor (GVAR(currentGrid) / _mapGrids) * _mapGrids) * 50; private _gridCenter = [_x + 25, _y + 25]; private _gridHeight = round getTerrainHeightASL _gridCenter; diff --git a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf index e7894e47c91..9864aea257e 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -1,99 +1,115 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Reads the ammo class config and updates the config cache + * Reads the ammo class config and caches it. * * Arguments: - * ammo - classname + * 0: Ammo * * Return Value: - * 0: _airFriction - * 1: _caliber - * 2: _bulletLength - * 3: _bulletMass - * 4: _transonicStabilityCoef - * 5: _dragModel - * 6: _ballisticCoefficients - * 7: _velocityBoundaries - * 8: _atmosphereModel - * 9: _ammoTempMuzzleVelocityShifts - * 10: _muzzleVelocityTable - * 11: _barrelLengthTable + * 0: Air friction coefficient + * 1: Caliber + * 2: Bullet length + * 3: Bullet mass + * 4: Transonic stability coefficient + * 5: Drag model + * 6: Ballistics coefficients + * 7: Velocity boundaries + * 8: Atmospheric model + * 9: Ammo tempature muzzle velocity shifts + * 10: Muzzle velocity array + * 11: Barrel Length array + * 12: Muzzle velocity standard deviation * * Example: - * ["ammo"] call ace_advanced_ballistics_fnc_readAmmoDataFromConfig + * "B_556x45_Ball" call ace_advanced_ballistics_fnc_readAmmoDataFromConfig * * Public: No */ -params ["_ammo"] - -TRACE_1("Reading Ammo Config",_ammo); +params ["_ammo"]; GVAR(ammoData) getOrDefaultCall [_ammo, { + TRACE_1("Reading Ammo Config",_ammo); + private _ammoConfig = configFile >> "CfgAmmo" >> _ammo; + private _airFriction = getNumber (_ammoConfig >> "airFriction"); + private _caliber = 0 max getNumber (_ammoConfig >> "ACE_caliber"); + private _bulletLength = 0 max getNumber (_ammoConfig >> "ACE_bulletLength"); + private _bulletMass = 0 max getNumber (_ammoConfig >> "ACE_bulletMass"); + private _transonicStabilityCoef = 0 max getNumber (_ammoConfig >> "ACE_transonicStabilityCoef") min 1; - private _airFriction = getNumber(_ammoConfig >> "airFriction"); - private _caliber = 0 max getNumber(_ammoConfig >> "ACE_caliber"); - private _bulletLength = 0 max getNumber(_ammoConfig >> "ACE_bulletLength"); - private _bulletMass = 0 max getNumber(_ammoConfig >> "ACE_bulletMass"); - private _transonicStabilityCoef = 0 max getNumber(_ammoConfig >> "ACE_transonicStabilityCoef") min 1; if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; - private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); + + private _dragModel = getNumber (_ammoConfig >> "ACE_dragModel"); + if !(_dragModel in [1, 2, 5, 6, 7, 8]) then { _dragModel = 1; }; - private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); + + private _ballisticCoefficients = getArray (_ammoConfig >> "ACE_ballisticCoefficients"); + if (_ballisticCoefficients isEqualTo []) then { _ballisticCoefficients = [0.5]; }; - private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries"); - private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere"); - if (_atmosphereModel isEqualTo "") then { + + private _velocityBoundaries = getArray (_ammoConfig >> "ACE_velocityBoundaries"); + private _atmosphereModel = getText (_ammoConfig >> "ACE_standardAtmosphere"); + + if (_atmosphereModel == "") then { _atmosphereModel = "ICAO"; }; + private _muzzleVelocityVariationSD = DEFAULT_MUZZLE_VELOCITY_VARIATION_SD; + if (isNumber (_ammoConfig >> "ACE_muzzleVelocityVariationSD")) then { - _muzzleVelocityVariationSD = getNumber(_ammoConfig >> "ACE_muzzleVelocityVariationSD") / 100; + _muzzleVelocityVariationSD = getNumber (_ammoConfig >> "ACE_muzzleVelocityVariationSD") / 100; }; - private _ammoTempMuzzleVelocityShifts = getArray(_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts"); - private _muzzleVelocityTable = getArray(_ammoConfig >> "ACE_muzzleVelocities"); - private _barrelLengthTable = getArray(_ammoConfig >> "ACE_barrelLengths"); - //Handle subsonic ammo that would have a huge muzzle velocity shift (when ballistic configs not explicitly defined) + private _ammoTempMuzzleVelocityShifts = getArray (_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts"); + private _muzzleVelocityTable = getArray (_ammoConfig >> "ACE_muzzleVelocities"); + private _barrelLengthTable = getArray (_ammoConfig >> "ACE_barrelLengths"); + + // Handle subsonic ammo that would have a huge muzzle velocity shift (when ballistic configs not explicitly defined) private _typicalSpeed = getNumber (_ammoConfig >> "typicalSpeed"); + if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then { - private _inheritedBarrelConfig = (_muzzleVelocityTable isNotEqualTo []) && {(configProperties [_ammoConfig, "(configName _x) == 'ACE_muzzleVelocities'", false]) isEqualTo []}; - private _inheritedTempConfig = (_ammoTempMuzzleVelocityShifts isNotEqualTo []) && {(configProperties [_ammoConfig, "(configName _x) == 'ACE_ammoTempMuzzleVelocityShifts'", false]) isEqualTo []}; + private _parentConfig = inheritsFrom _ammoConfig; + private _inheritedBarrelConfig = (_muzzleVelocityTable isNotEqualTo []) && {(_parentConfig >> "ACE_muzzleVelocities") == (_ammoConfig >> "ACE_muzzleVelocities")}; + private _inheritedTempConfig = (_ammoTempMuzzleVelocityShifts isNotEqualTo []) && {(_parentConfig >> "ACE_ammoTempMuzzleVelocityShifts") == (_ammoConfig >> "ACE_ammoTempMuzzleVelocityShifts")}; TRACE_3("subsonic",_typicalSpeed,_inheritedBarrelConfig,_inheritedTempConfig); + if (_inheritedBarrelConfig || _inheritedTempConfig) then { - private _parentConfig = inheritsFrom _ammoConfig; private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed"); WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_ammo,_typicalSpeed,configName _parentConfig,_parentSpeed); - if (_parentSpeed <= 0) exitWith {//Handle weird or null parent + + if (_parentSpeed <= 0) exitWith { // Handle weird or null parent _muzzleVelocityTable = []; _ammoTempMuzzleVelocityShifts = []; }; + + private _grandparentConfig = inheritsFrom _parentConfig; private _linearMuliplier = _typicalSpeed / _parentSpeed; + if (_inheritedBarrelConfig) then { - if ((configProperties [_parentConfig, "(configName _x) == 'ACE_muzzleVelocities'", false]) isNotEqualTo []) then { + _muzzleVelocityTable = if ((_grandparentConfig >> "ACE_muzzleVelocities") != (_parentConfig >> "ACE_muzzleVelocities")) then { TRACE_2("Parent Has Defined Barrel MV",_linearMuliplier,_muzzleVelocityTable); - { _muzzleVelocityTable set [_forEachIndex, (_x * _linearMuliplier)]; } forEach _muzzleVelocityTable; + _muzzleVelocityTable vectorMultiply _linearMuliplier } else { TRACE_2("Parent DOES NOT Have Defined Barrel MV",_linearMuliplier,_muzzleVelocityTable); - _muzzleVelocityTable = []; + [] }; }; + if (_inheritedTempConfig) then { - if ((configProperties [_parentConfig, "(configName _x) == 'ACE_ammoTempMuzzleVelocityShifts'", false]) isNotEqualTo []) then { + _ammoTempMuzzleVelocityShifts = if ((_grandparentConfig >> "ACE_ammoTempMuzzleVelocityShifts") != (_parentConfig >> "ACE_ammoTempMuzzleVelocityShifts")) then { TRACE_2("Parent Has Defined Ammo Temp Shifts",_linearMuliplier,_muzzleVelocityTable); - { _ammoTempMuzzleVelocityShifts set [_forEachIndex, (_x * _linearMuliplier)]; } forEach _ammoTempMuzzleVelocityShifts; + _ammoTempMuzzleVelocityShifts vectorMultiply _linearMuliplier } else { TRACE_2("Parent DOES NOT Have Defined Ammo Temp Shifts",_linearMuliplier,_muzzleVelocityTable); - _ammoTempMuzzleVelocityShifts = []; + [] }; }; }; diff --git a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf index 9ea28a9a818..f9db8d6c16f 100644 --- a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf @@ -1,17 +1,16 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * - * Reads the weapon class config and updates the config cache + * Reads the weapon class config and caches it. * * Arguments: * 0: Weapon * 1: Muzzle (optional) * * Return Value: - * 0: _barrelTwist - * 1: _twistDirection - * 2: _barrelLength + * 0: Barrel twist + * 1: Twist direction + * 2: Barrel length * * Example: * [currentWeapon player, currentMuzzle player] call ace_advanced_ballistics_fnc_readWeaponDataFromConfig @@ -31,16 +30,16 @@ GVAR(weaponData) getOrDefaultCall [[_weapon, _muzzle], { configFile >> "CfgWeapons" >> _weapon >> _muzzle }; - private _barrelTwist = 0 max getNumber(_weaponConfig >> "ACE_barrelTwist"); - private _twistDirection = parseNumber (_barrelTwist != 0); - if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { - _twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection"); - if !(_twistDirection in [-1, 0, 1]) then { - _twistDirection = 1; - }; + private _barrelTwist = 0 max getNumber (_weaponConfig >> "ACE_barrelTwist"); + private _twistDirection = if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { + private _twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection"); + + [1, _twistDirection] select (_twistDirection in [-1, 0, 1]) + } else { + parseNumber (_barrelTwist != 0) }; - private _barrelLength = 0 max getNumber(_weaponConfig >> "ACE_barrelLength"); + private _barrelLength = 0 max getNumber (_weaponConfig >> "ACE_barrelLength"); [_barrelTwist, _twistDirection, _barrelLength] }, true] // return diff --git a/addons/advanced_ballistics/initKeybinds.inc.sqf b/addons/advanced_ballistics/initKeybinds.inc.sqf index 102107dadcf..715df22b1f3 100644 --- a/addons/advanced_ballistics/initKeybinds.inc.sqf +++ b/addons/advanced_ballistics/initKeybinds.inc.sqf @@ -1,10 +1,12 @@ -["ACE3 Equipment", QGVAR(ProtractorKey), localize LSTRING(ProtractorKey), +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +["ACE3 Equipment", QGVAR(ProtractorKey), LLSTRING(ProtractorKey), { // Conditions: canInteract if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false}; // Statement - [] call FUNC(displayProtractor); + [] call FUNC(displayProtractor) // return }, {false}, -[37, [true, true, false]], false, 0] call CBA_fnc_addKeybind; // (CTRL + SHIFT + K) +[DIK_K, [true, true, false]], false, 0] call CBA_fnc_addKeybind; // (CTRL + SHIFT + K) diff --git a/addons/advanced_ballistics/initSettings.inc.sqf b/addons/advanced_ballistics/initSettings.inc.sqf index 28a1d6d8262..4ebfe4d2ccc 100644 --- a/addons/advanced_ballistics/initSettings.inc.sqf +++ b/addons/advanced_ballistics/initSettings.inc.sqf @@ -1,4 +1,4 @@ -private _category = format ["ACE %1", localize LSTRING(DisplayName)]; +private _category = format ["ACE %1", LLSTRING(DisplayName)]; [ QGVAR(enabled), "CHECKBOX", diff --git a/addons/advanced_ballistics/script_component.hpp b/addons/advanced_ballistics/script_component.hpp index bbd659670f6..4431c96780f 100644 --- a/addons/advanced_ballistics/script_component.hpp +++ b/addons/advanced_ballistics/script_component.hpp @@ -21,10 +21,6 @@ #define ABSOLUTE_ZERO_IN_CELSIUS -273.15 #define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS) #define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS) -#define UNIVERSAL_GAS_CONSTANT 8.314 -#define WATER_VAPOR_MOLAR_MASS 0.018016 -#define DRY_AIR_MOLAR_MASS 0.028964 -#define SPECIFIC_GAS_CONSTANT_DRY_AIR 287.058 #define STD_AIR_DENSITY_ICAO 1.22498 #define STD_AIR_DENSITY_ASM 1.20885 @@ -32,5 +28,3 @@ #define DEFAULT_MUZZLE_VELOCITY_VARIATION_SD 0.003 #define BULLET_TRACE_MIN_VELOCITY 500 - -#define EXTENSION_REQUIRED_VERSION "1.0" From dd5b2084795ba88dcb2ee0ec5145acef9b13207f Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 1 Feb 2026 10:52:59 -0800 Subject: [PATCH 2/4] Update addons/advanced_ballistics/functions/fnc_handleFired.sqf Co-authored-by: PabstMirror --- addons/advanced_ballistics/functions/fnc_handleFired.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index 3523458e025..7fc58b2f5b2 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -108,7 +108,7 @@ private _stabilityFactor = if (_caliber * _bulletLength * _bulletMass * _barrelT }; private _barometricPressure = ((getPosASL _projectile) select 2) call EFUNC(weather,calculateBarometricPressure); - _stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor); + [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor); } else { 1.5 }; From 7e428b96f08e43c7365bfaac64a8f8e5c8372fe7 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Mon, 2 Feb 2026 20:47:45 +0100 Subject: [PATCH 3/4] Clean up protractor --- addons/advanced_ballistics/RscTitles.hpp | 29 ++------------- .../functions/fnc_displayProtractor.sqf | 37 +++++++------------ 2 files changed, 16 insertions(+), 50 deletions(-) diff --git a/addons/advanced_ballistics/RscTitles.hpp b/addons/advanced_ballistics/RscTitles.hpp index 670585b4857..a835e9ce4f2 100644 --- a/addons/advanced_ballistics/RscTitles.hpp +++ b/addons/advanced_ballistics/RscTitles.hpp @@ -1,33 +1,9 @@ class RscTitles { - class RscTurretDial { - idd = -1; - movingEnable = 0; - duration = 5; - fadeIn = "false"; - fadeOut = "false"; - class controls { - class RscTurretDial { - idc = 132949; - type = 0; - style = 128; - font = "TahomaB"; - colorBackground[] = {0, 0, 0, 0.8}; - colorText[] = {1, 1, 1, 1}; - x = "SafeZoneX + 0.0025"; - y = "SafeZoneY + 0.0025"; - w = 0.10; - h = 0.05; - sizeEx = 0.03; - text = ""; - }; - }; - }; - class RscProtractor { idd = -1; onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(rscProtractor),_this select 0)]); movingEnable = 0; - duration = 60; + duration = 1e10; fadeIn = "false"; fadeOut = "false"; class controls { @@ -44,10 +20,11 @@ class RscTitles { h = 0.2*4/3; size = 0.034; sizeEx = 0.027; - text = ""; + text = QPATHTOF(UI\protractor.paa); }; class RscProtractorMarker: RscProtractorBase { idc = 132951; + text = QPATHTOF(UI\protractor_marker.paa); }; }; }; diff --git a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf index 753f52e2d16..22577663e36 100644 --- a/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf +++ b/addons/advanced_ballistics/functions/fnc_displayProtractor.sqf @@ -17,7 +17,7 @@ if (GVAR(protractor)) exitWith { GVAR(protractor) = false; - 1 cutText ["", "PLAIN"]; + QGVAR(protractor) cutText ["", "PLAIN"]; true // return }; @@ -25,41 +25,30 @@ if (weaponLowered ACE_player || !isNull objectParent ACE_player || currentWeapon false // return }; -2 cutText ["", "PLAIN"]; +// Close weather's wind info, in case it's open EGVAR(weather,WindInfo) = false; (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; + +// Display the protractor GVAR(protractor) = true; +QGVAR(protractor) cutRsc ["RscProtractor", "PLAIN", 1, false]; +// Update angle marker every frame [{ - disableSerialization; - - params ["", "_idPFH"]; - private _currentWeapon = currentWeapon ACE_player; if (!GVAR(protractor) || weaponLowered ACE_player || _currentWeapon != primaryWeapon ACE_player) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; GVAR(protractor) = false; - 1 cutText ["", "PLAIN"]; - _idPFH call CBA_fnc_removePerFrameHandler; + QGVAR(protractor) cutText ["", "PLAIN"]; }; - 1 cutRsc ["RscProtractor", "PLAIN", 1, false]; - - private _display = uiNamespace getVariable QGVAR(rscProtractor); - private _ctrl1 = _display displayCtrl 132950; - - _ctrl1 ctrlSetScale 1; - _ctrl1 ctrlCommit 0; - _ctrl1 ctrlSetText QPATHTOF(UI\protractor.paa); - _ctrl1 ctrlSetTextColor [1, 1, 1, 1]; + disableSerialization; - private _ctrl2 = _display displayCtrl 132951; + private _ctrlMarker = (uiNamespace getVariable QGVAR(rscProtractor)) displayCtrl 132951; - _ctrl2 ctrlSetScale 1; - _ctrl2 ctrlSetPosition [safeZoneX + 0.001, safeZoneY - 0.001 - 0.1074 * (-0.86 max ((ACE_player weaponDirection _currentWeapon) select 2) min 0.86), 0.2, 0.2 * 4/3]; - _ctrl2 ctrlCommit 0; - _ctrl2 ctrlSetText QPATHTOF(UI\protractor_marker.paa); - _ctrl2 ctrlSetTextColor [1, 1, 1, 1]; -}, 0.1] call CBA_fnc_addPerFrameHandler; + _ctrlMarker ctrlSetPosition [safeZoneX + 0.001, safeZoneY - 0.001 - 0.1074 * (-0.86 max ((ACE_player weaponDirection _currentWeapon) select 2) min 0.86), 0.2, 0.2 * 4/3]; + _ctrlMarker ctrlCommit 0; +}] call CBA_fnc_addPerFrameHandler; true // return From 51aaa886569b7353ff1e3197ffff34cce4ca0169 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Tue, 3 Feb 2026 17:04:59 -0600 Subject: [PATCH 4/4] Update fnc_displayWindInfo.sqf --- addons/weather/functions/fnc_displayWindInfo.sqf | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/weather/functions/fnc_displayWindInfo.sqf b/addons/weather/functions/fnc_displayWindInfo.sqf index 871d262a84d..79eadb5f730 100644 --- a/addons/weather/functions/fnc_displayWindInfo.sqf +++ b/addons/weather/functions/fnc_displayWindInfo.sqf @@ -25,7 +25,6 @@ if (GVAR(WindInfo)) exitWith { }; EGVAR(advanced_ballistics,Protractor) = false; -1 cutText ["", "PLAIN"]; GVAR(WindInfo) = true;