ACE3/TO_MERGE/agm/FireControlSystem/functions/fn_keyUp.sqf

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;