mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
161 lines
7.2 KiB
Plaintext
161 lines
7.2 KiB
Plaintext
/*
|
|
* Author: KoffeinFlummi
|
|
*
|
|
* Calculates the offsets for all weapons needed to hit the current target.
|
|
*
|
|
* Arguments:
|
|
* 0: The vehicle
|
|
* 1: Range Override (Optional)
|
|
*
|
|
* Return Value:
|
|
* none
|
|
*/
|
|
|
|
private ["_ammoType", "_viewDiff", "_posArrival", "_airFriction", "_timeToLive", "_maxElev", "_vehicle", "_posTarget", "_distance", "_simulationStep", "_posX", "_velocityMagnitude", "_magazines", "_movingAzimuth", "_FCSElevation", "_velocityX", "_velocityY", "_weaponDirection", "_velocityTarget", "_FCSAzimuth", "_FCSMagazines", "_dirArrival", "_i", "_magazineType", "_angleTarget", "_offset", "_timeToTarget", "_initSpeed"];
|
|
|
|
_vehicle = _this select 0;
|
|
_distance = _this select 1;
|
|
|
|
_magazines = magazines _vehicle;
|
|
|
|
if (_distance == 0) then {
|
|
_distance = [
|
|
getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "AGM_FCSDistanceInterval"),
|
|
getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "AGM_FCSMaxDistance"),
|
|
getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "AGM_FCSMinDistance")
|
|
] call AGM_Core_fnc_getTargetDistance; // maximum distance: 5000m, 5m precision
|
|
};
|
|
|
|
_weaponDirection = _vehicle weaponDirection currentWeapon _vehicle;
|
|
_angleTarget = asin (_weaponDirection select 2);
|
|
|
|
if (count _this > 2) then {
|
|
_distance = _this select 2;
|
|
};
|
|
|
|
if (!(isNil "AGM_FCS_backgroundCalculation") and {!(scriptDone AGM_FCS_backgroundCalculation)}) then {
|
|
terminate AGM_FCS_backgroundCalculation;
|
|
};
|
|
|
|
// MOVING TARGETS
|
|
_movingAzimuth = 0;
|
|
if (time - AGM_FCSTime > 1 and AGM_FCSTime != -1 and count _this < 3) then {
|
|
// calculate speed of target
|
|
_posTarget = [
|
|
(getPos _vehicle select 0) + _distance * (_weaponDirection select 0),
|
|
(getPos _vehicle select 1) + _distance * (_weaponDirection select 1),
|
|
(getPos _vehicle select 2) + _distance * (_weaponDirection select 2)
|
|
];
|
|
_velocityTarget = [
|
|
((_posTarget select 0) - (AGM_FCSPosition select 0)) / (time - AGM_FCSTime),
|
|
((_posTarget select 1) - (AGM_FCSPosition select 1)) / (time - AGM_FCSTime),
|
|
((_posTarget select 2) - (AGM_FCSPosition select 2)) / (time - AGM_FCSTime)
|
|
];
|
|
|
|
// estimate time to target
|
|
_magazineType = currentMagazine _vehicle;
|
|
_ammoType = getText (configFile >> "CfgMagazines" >> _magazineType >> "ammo");
|
|
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineType >> "initSpeed");
|
|
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
|
_timeToLive = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "timeToLive");
|
|
_simulationStep = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "simulationStep");
|
|
|
|
if (_simulationStep != 0) then {
|
|
_posX = 0;
|
|
_velocityX = _initSpeed;
|
|
_velocityY = 0;
|
|
_timeToTarget = 0;
|
|
for "_i" from 1 to ((floor (_timeToLive / _simulationStep)) + 1) do {
|
|
_posX = _posX + _velocityX * _simulationStep;
|
|
if (_posX >= _distance) exitWith { // bullet passed the target
|
|
_timeToTarget = _i * _simulationStep;
|
|
};
|
|
_velocityMagnitude = sqrt (_velocityX^2 + _velocityY^2);
|
|
_velocityX = _velocityX + _velocityX * _velocityMagnitude * _airFriction * _simulationStep;
|
|
_velocityY = _velocityY + _velocityY * _velocityMagnitude * _airFriction * _simulationStep - 9.81 * _simulationStep;
|
|
};
|
|
|
|
// calculate offsets
|
|
_posArrival = [
|
|
(_posTarget select 0) + (_velocityTarget select 0) * _timeToTarget,
|
|
(_posTarget select 1) + (_velocityTarget select 1) * _timeToTarget,
|
|
(_posTarget select 2) + (_velocityTarget select 2) * _timeToTarget
|
|
];
|
|
_dirArrival = [
|
|
((_posArrival select 0) - (getPos _vehicle select 0)) / (_posArrival distance (getPos _vehicle)),
|
|
((_posArrival select 1) - (getPos _vehicle select 1)) / (_posArrival distance (getPos _vehicle)),
|
|
((_posArrival select 2) - (getPos _vehicle select 2)) / (_posArrival distance (getPos _vehicle))
|
|
];
|
|
|
|
_movingAzimuth = ((_dirArrival select 0) atan2 (_dirArrival select 1)) - ((_weaponDirection select 0) atan2 (_weaponDirection select 1));
|
|
_angleTarget = asin (_dirArrival select 2);
|
|
_distance = floor (_posArrival distance (getPos _vehicle));
|
|
};
|
|
};
|
|
AGM_FCSEnabled = false;
|
|
AGM_FCSTime = -1;
|
|
|
|
// CALCULATE AZIMUTH CORRECTION
|
|
_viewDiff = _vehicle getVariable "AGM_FCSViewDiff";
|
|
_FCSAzimuth = _movingAzimuth;
|
|
if (_viewDiff != 0) then {
|
|
_FCSAzimuth = (atan (_distance / _viewDiff) - (abs _viewDiff / _viewDiff) * 90) + _movingAzimuth;
|
|
};
|
|
|
|
// CALCULATE OFFSET FOR CURRENT WEAPON
|
|
_FCSMagazines = [];
|
|
_FCSElevation = [];
|
|
|
|
_magazineType = currentMagazine _vehicle;
|
|
_ammoType = getText (configFile >> "CfgMagazines" >> _magazineType >> "ammo");
|
|
if !(getText (configFile >> "CfgAmmo" >> _ammoType >> "simulation") == "shotMissile") then {
|
|
_maxElev = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "Turrets" >> "MainTurret" >> "maxElev");
|
|
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineType >> "initSpeed");
|
|
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
|
_timeToLive = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "timeToLive");
|
|
_simulationStep = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "simulationStep");
|
|
|
|
_offset = [_distance, _angleTarget, _maxElev, _initSpeed, _airFriction, _timeToLive, _simulationStep] call AGM_FCS_fnc_getAngle;
|
|
|
|
_FCSMagazines = _FCSMagazines + [_magazineType];
|
|
_FCSElevation = _FCSElevation + [_offset];
|
|
};
|
|
|
|
_vehicle setVariable ["AGM_FCSDistance", _distance, true];
|
|
_vehicle setVariable ["AGM_FCSMagazines", _FCSMagazines, true];
|
|
_vehicle setVariable ["AGM_FCSElevation", _FCSElevation, true];
|
|
_vehicle setVariable ["AGM_FCSAzimuth", _FCSAzimuth, true];
|
|
|
|
// CALCULATE OFFSETS FOR OTHER WEAPONS IN THE BACKGROUND
|
|
AGM_FCS_backgroundCalculation = [_vehicle, _magazines, _distance, _angleTarget, _FCSMagazines, _FCSElevation] spawn {
|
|
_vehicle = _this select 0;
|
|
_magazines = _this select 1;
|
|
_distance = _this select 2;
|
|
_angleTarget = _this select 3;
|
|
_FCSMagazines = _this select 4;
|
|
_FCSElevation = _this select 5;
|
|
|
|
{
|
|
if !(_x in _FCSMagazines) then {
|
|
_ammoType = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
|
if !(getText (configFile >> "CfgAmmo" >> _ammoType >> "simulation") == "shotMissile") then {
|
|
_maxElev = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "Turrets" >> "MainTurret" >> "maxElev");
|
|
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _x >> "initSpeed");
|
|
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
|
_timeToLive = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "timeToLive");
|
|
_simulationStep = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "simulationStep");
|
|
|
|
_offset = [_distance, _angleTarget, _maxElev, _initSpeed, _airFriction, _timeToLive, _simulationStep] call AGM_FCS_fnc_getAngle;
|
|
|
|
_FCSMagazines = _FCSMagazines + [_x];
|
|
_FCSElevation = _FCSElevation + [_offset];
|
|
};
|
|
};
|
|
} forEach _magazines;
|
|
|
|
_vehicle setVariable ["AGM_FCSMagazines", _FCSMagazines, true];
|
|
_vehicle setVariable ["AGM_FCSElevation", _FCSElevation, true];
|
|
};
|
|
|
|
[format ["%1: %2", localize "STR_AGM_FireControlSystem_ZeroedTo", _distance]] call AGM_Core_fnc_displayTextStructured;
|