diff --git a/ace_advanced_ballistics.dll b/ace_advanced_ballistics.dll index e2e8fe09d83..4f8f0e7a398 100644 Binary files a/ace_advanced_ballistics.dll and b/ace_advanced_ballistics.dll differ diff --git a/ace_advanced_ballistics_x64.dll b/ace_advanced_ballistics_x64.dll index d65f55f4bd6..5f77553aa5e 100644 Binary files a/ace_advanced_ballistics_x64.dll and b/ace_advanced_ballistics_x64.dll differ diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index d849fa76c33..8a41e1c38e6 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -36,10 +36,10 @@ if (!GVAR(atmosphereModeTBH)) then { }; private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, _temperature, _barometricPressure, _relativeHumidity, _bc, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; diff --git a/addons/rangecard/functions/fnc_updateRangeCard.sqf b/addons/rangecard/functions/fnc_updateRangeCard.sqf index 77ec68c0f73..9ab6fc6341b 100644 --- a/addons/rangecard/functions/fnc_updateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_updateRangeCard.sqf @@ -156,10 +156,10 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]]; if (isNil {_cacheEntry}) then { private _scopeBaseAngle = if (!_useABConfig) then { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { - private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; + private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then { diff --git a/addons/scopes/CfgWeapons.hpp b/addons/scopes/CfgWeapons.hpp index 5b36c59e9f4..1549baeba2d 100644 --- a/addons/scopes/CfgWeapons.hpp +++ b/addons/scopes/CfgWeapons.hpp @@ -255,6 +255,7 @@ class CfgWeapons { class pdw2000_base_F: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 3.08883; + ACE_RailBaseAngle = 0.019366; }; class arifle_AKS_base_F: Rifle_Base_F { @@ -306,13 +307,16 @@ class CfgWeapons { }; class SMG_01_Base: Rifle_Short_Base_F { - ACE_RailHeightAboveBore = 8.85355; + ACE_RailHeightAboveBore = 4.85355; + ACE_RailBaseAngle = 0.0250956; }; class SMG_02_base_F: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 4.41831; + ACE_RailBaseAngle = 0.0217724; }; class SMG_05_base_F: Rifle_Short_Base_F { ACE_RailHeightAboveBore = 4.05169; + ACE_RailBaseAngle = 0.019366; }; class Tavor_base_F: Rifle_Base_F {}; @@ -362,13 +366,14 @@ class CfgWeapons { ACE_RailHeightAboveBore = 2.83284; }; class srifle_DMR_02_F: DMR_02_base_F { - ACE_RailHeightAboveBore = 4.43913; + ACE_RailHeightAboveBore = 3.43913; }; class srifle_DMR_03_F: DMR_03_base_F { ACE_RailHeightAboveBore = 4.0795; }; class srifle_DMR_04_F: DMR_04_base_F { - ACE_RailHeightAboveBore = 5.38022; + ACE_RailHeightAboveBore = 2.38022; + ACE_RailBaseAngle = 0.019366; }; class srifle_DMR_05_blk_F: DMR_05_base_F { ACE_RailHeightAboveBore = 3.91334; diff --git a/addons/scopes/XEH_PREP.hpp b/addons/scopes/XEH_PREP.hpp index a8489fe5855..f420fab2bcd 100644 --- a/addons/scopes/XEH_PREP.hpp +++ b/addons/scopes/XEH_PREP.hpp @@ -5,6 +5,7 @@ PREP(applyScopeAdjustment); PREP(calculateZeroAngleCorrection); PREP(canAdjustZero); PREP(firedEH); +PREP(getBaseAngle); PREP(getBoreHeight); PREP(getCurrentZeroRange); PREP(getOptics); diff --git a/addons/scopes/XEH_postInit.sqf b/addons/scopes/XEH_postInit.sqf index 83fad080770..1ee833aa094 100644 --- a/addons/scopes/XEH_postInit.sqf +++ b/addons/scopes/XEH_postInit.sqf @@ -13,6 +13,7 @@ GVAR(Optics) = ["", "", ""]; GVAR(Guns) = ["", "", ""]; GVAR(canAdjustElevation) = [false, false, false]; GVAR(canAdjustWindage) = [false, false, false]; +GVAR(baseAngle) = [0, 0, 0]; GVAR(boreHeight) = [0, 0, 0]; GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; diff --git a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf index 21ae70f9bda..1c04ef6c8b7 100644 --- a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -32,11 +32,11 @@ if (_initSpeedCoef < 0) then { _initSpeed = _initSpeed * (-1 * _initSpeedCoef); }; -private _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _oldZeroRange, _initSpeed, _airFriction, 0]; +private _zeroAngle = "ace_advanced_ballistics" callExtension format ["replicateVanillaZero:%1:%2:%3", _oldZeroRange, _initSpeed, _airFriction]; private _vanillaZero = parseNumber _zeroAngle; private _trueZero = if (!_advancedBallistics) then { - _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngleVanilla:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; + _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _newZeroRange, _initSpeed, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { // Get Weapon and Ammo Configurations @@ -62,7 +62,7 @@ private _trueZero = if (!_advancedBallistics) then { _initSpeed = _initSpeed + _ammoTemperatureVelocityShift; }; - _zeroAngle = "ace_advanced_ballistics" callExtension format ["zeroAngle:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel]; + _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _newZeroRange, _initSpeed, _boreHeight, GVAR(zeroReferenceTemperature), GVAR(zeroReferenceBarometricPressure), GVAR(zeroReferenceHumidity), _ballisticCoefficients select 0, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index 670db51fe03..cbe846f1ccc 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -32,6 +32,7 @@ _zeroing = _zeroing vectorMultiply MRAD_TO_DEG(1); if (GVAR(correctZeroing)) then { private _advancedBallistics = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; + private _baseAngle = GVAR(baseAngle) select _weaponIndex; private _boreHeight = GVAR(boreHeight) select _weaponIndex; private _oldZeroRange = currentZeroing _unit; private _newZeroRange = [_unit] call FUNC(getCurrentZeroRange); @@ -39,7 +40,7 @@ if (GVAR(correctZeroing)) then { if (isNil "_zeroCorrection") then { _zeroCorrection = [_oldZeroRange, _newZeroRange, _boreHeight, _weapon, _ammo, _magazine, _advancedBallistics] call FUNC(calculateZeroAngleCorrection); }; - _zeroing = _zeroing vectorAdd [0, 0, _zeroCorrection]; + _zeroing = _zeroing vectorAdd [0, 0, _zeroCorrection - _baseAngle]; }; if (_zeroing isEqualTo [0, 0, 0]) exitWith {}; diff --git a/addons/scopes/functions/fnc_getBaseAngle.sqf b/addons/scopes/functions/fnc_getBaseAngle.sqf new file mode 100644 index 00000000000..103ece8308f --- /dev/null +++ b/addons/scopes/functions/fnc_getBaseAngle.sqf @@ -0,0 +1,31 @@ +/* + * Author: Ruthberg + * Gets the base angle of the rail on the weapon with the given weapon index + * + * Arguments: + * 0: Unit + * 1: Weapon index + * + * Return Value: + * base angle + * + * Example: + * [player, 0] call ace_scopes_fnc_getBaseAngle + * + * Public: Yes + */ +#include "script_component.hpp" + +params ["_player", "_weaponIndex"]; + +if (_weaponIndex < 0 || {_weaponIndex > 2}) exitWith { 0 }; + +private _weaponClass = [primaryWeapon _player, secondaryWeapon _player, handgunWeapon _player] select _weaponIndex; + +private _baseAngle = DEFAULT_RAIL_BASE_ANGLE; +private _weaponConfig = configFile >> "CfgWeapons" >> _weaponClass; +if (isNumber (_weaponConfig >> "ACE_RailBaseAngle")) then { + _baseAngle = getNumber(_weaponConfig >> "ACE_RailBaseAngle"); +}; + +_baseAngle diff --git a/addons/scopes/functions/fnc_getBoreHeight.sqf b/addons/scopes/functions/fnc_getBoreHeight.sqf index 98fb75f78a6..8b1cd627cf2 100644 --- a/addons/scopes/functions/fnc_getBoreHeight.sqf +++ b/addons/scopes/functions/fnc_getBoreHeight.sqf @@ -10,7 +10,7 @@ * bore height * * Example: - * [player] call ace_scopes_fnc_getBoreHeight + * [player, 0] call ace_scopes_fnc_getBoreHeight * * Public: Yes */ diff --git a/addons/scopes/functions/fnc_inventoryCheck.sqf b/addons/scopes/functions/fnc_inventoryCheck.sqf index 817d301221c..c60ad5ecc80 100644 --- a/addons/scopes/functions/fnc_inventoryCheck.sqf +++ b/addons/scopes/functions/fnc_inventoryCheck.sqf @@ -69,9 +69,10 @@ private _newGuns = [primaryWeapon _player, secondaryWeapon _player, handgunWeapo _adjustment set [_forEachIndex, [0, 0, 0]]; _updateAdjustment = true; }; - + + GVAR(baseAngle) set [_x, [_player, _x] call FUNC(getBaseAngle)]; GVAR(boreHeight) set [_x, [_player, _x] call FUNC(getBoreHeight)]; - + if ((_newOptics select _x) == "") then { // Check if the weapon comes with an integrated optic private _weaponConfig = configFile >> "CfgWeapons" >> (_newGuns select _x); diff --git a/addons/scopes/script_component.hpp b/addons/scopes/script_component.hpp index a797b36191a..58ae637ef34 100644 --- a/addons/scopes/script_component.hpp +++ b/addons/scopes/script_component.hpp @@ -14,6 +14,8 @@ #define MINOR_INCREMENT false #define MAJOR_INCREMENT true +#define DEFAULT_RAIL_BASE_ANGLE 0.0086 + #ifdef DEBUG_ENABLED_SCOPES #define DEBUG_MODE_FULL #endif diff --git a/extensions/advanced_ballistics/AdvancedBallistics.cpp b/extensions/advanced_ballistics/AdvancedBallistics.cpp index 79382e85802..d8166e207c0 100644 --- a/extensions/advanced_ballistics/AdvancedBallistics.cpp +++ b/extensions/advanced_ballistics/AdvancedBallistics.cpp @@ -152,7 +152,33 @@ double calculateRetard(int DragFunction, double DragCoefficient, double Velocity return 0.0; } -double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double airFriction, double boreHeight) { +float replicateVanillaZero(float zeroRange, float muzzleVelocity, float airFriction) { + const float maxDeltaT = 0.05f; + float time = 0.0f; + ace::vector3 curShotPos = { 0, 0, 0 }; + ace::vector3 speed = { muzzleVelocity, 0, 0 }; + + while (time < 8.0f) { + float distLeft = zeroRange - curShotPos.x(); + float traveled = speed.x() * maxDeltaT; + if (distLeft < traveled) { + float deltaT = distLeft / speed.x(); + speed -= { 0, GRAVITY * deltaT, 0 }; + curShotPos += speed * deltaT; + time += deltaT; + break; + } else { + float deltaT = maxDeltaT; + curShotPos += speed * deltaT; + time += deltaT; + speed += speed * (speed.magnitude() * airFriction * deltaT); + speed -= { 0, GRAVITY * deltaT, 0 }; + } + } + return -std::atan(curShotPos.y() / zeroRange); +} + +double calculateVanillaZero(double zeroRange, double muzzleVelocity, double airFriction, double boreHeight) { double zeroAngle = 0.0f; double deltaT = 1.0 / std::max(100.0, zeroRange); @@ -197,7 +223,7 @@ double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double double offset = -std::atan(y / zeroRange); zeroAngle += offset; - if (std::abs(offset) < 0.0001f) { + if (std::abs(offset) < 0.00001f) { break; } } @@ -205,7 +231,7 @@ double calculateVanillaZeroAngle(double zeroRange, double muzzleVelocity, double return zeroAngle; } -double calculateZeroAngle(double zeroRange, double muzzleVelocity, double boreHeight, double temperature, double pressure, double humidity, double ballisticCoefficient, int dragModel, char* atmosphereModel) { +double calculateAdvancedZero(double zeroRange, double muzzleVelocity, double boreHeight, double temperature, double pressure, double humidity, double ballisticCoefficient, int dragModel, char* atmosphereModel) { double zeroAngle = 0.0f; double deltaT = 1.0 / std::max(100.0, zeroRange); @@ -253,7 +279,7 @@ double calculateZeroAngle(double zeroRange, double muzzleVelocity, double boreHe double offset = -std::atan(y / zeroRange); zeroAngle += offset; - if (std::abs(offset) < 0.0001f) { + if (std::abs(offset) < 0.00001f) { break; } } @@ -642,18 +668,28 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); EXTENSION_RETURN(); - } else if (!strcmp(mode, "zeroAngleVanilla")) { + } else if (!strcmp(mode, "replicateVanillaZero")) { + float zeroRange = strtof(strtok_s(NULL, ":", &next_token), NULL); + float initSpeed = strtof(strtok_s(NULL, ":", &next_token), NULL); + float airFriction = strtof(strtok_s(NULL, ":", &next_token), NULL); + + float zeroAngle = replicateVanillaZero(zeroRange, initSpeed, airFriction); + + outputStr << DEGREES(zeroAngle); + strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); + EXTENSION_RETURN(); + } else if (!strcmp(mode, "calcZero")) { double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL); double initSpeed = strtod(strtok_s(NULL, ":", &next_token), NULL); double airFriction = strtod(strtok_s(NULL, ":", &next_token), NULL); double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL); - double zeroAngle = calculateVanillaZeroAngle(zeroRange, initSpeed, airFriction, boreHeight); + double zeroAngle = calculateVanillaZero(zeroRange, initSpeed, airFriction, boreHeight); outputStr << DEGREES(zeroAngle); strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE); EXTENSION_RETURN(); - } else if (!strcmp(mode, "zeroAngle")) { + } else if (!strcmp(mode, "calcZeroAB")) { double zeroRange = strtod(strtok_s(NULL, ":", &next_token), NULL); double muzzleVelocity = strtod(strtok_s(NULL, ":", &next_token), NULL); double boreHeight = strtod(strtok_s(NULL, ":", &next_token), NULL); @@ -664,7 +700,7 @@ void __stdcall RVExtension(char *output, int outputSize, const char *function) int dragModel = strtol(strtok_s(NULL, ":", &next_token), NULL, 10); char* atmosphereModel = strtok_s(NULL, ":", &next_token); - double zeroAngle = calculateZeroAngle(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel); + double zeroAngle = calculateAdvancedZero(zeroRange, muzzleVelocity, boreHeight, temperature, pressure, humidity, ballisticCoefficient, dragModel, atmosphereModel); outputStr << DEGREES(zeroAngle); strncpy_s(output, outputSize, outputStr.str().c_str(), _TRUNCATE);