mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge pull request #5747 from acemod/scopes-zeroing-fix
Scopes - Improved zero angle calculation
This commit is contained in:
commit
fbaa071a4e
Binary file not shown.
Binary file not shown.
@ -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)
|
||||
};
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -5,6 +5,7 @@ PREP(applyScopeAdjustment);
|
||||
PREP(calculateZeroAngleCorrection);
|
||||
PREP(canAdjustZero);
|
||||
PREP(firedEH);
|
||||
PREP(getBaseAngle);
|
||||
PREP(getBoreHeight);
|
||||
PREP(getCurrentZeroRange);
|
||||
PREP(getOptics);
|
||||
|
@ -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]];
|
||||
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
@ -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 {};
|
||||
|
31
addons/scopes/functions/fnc_getBaseAngle.sqf
Normal file
31
addons/scopes/functions/fnc_getBaseAngle.sqf
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
* Gets the base angle of the rail on the weapon with the given weapon index
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Weapon index <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* base angle <NUMBER>
|
||||
*
|
||||
* 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
|
@ -10,7 +10,7 @@
|
||||
* bore height <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player] call ace_scopes_fnc_getBoreHeight
|
||||
* [player, 0] call ace_scopes_fnc_getBoreHeight
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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<float> curShotPos = { 0, 0, 0 };
|
||||
ace::vector3<float> 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);
|
||||
|
Loading…
Reference in New Issue
Block a user