2023-09-12 18:58:10 +00:00
|
|
|
#include "..\script_component.hpp"
|
2015-01-11 16:42:31 +00:00
|
|
|
/*
|
|
|
|
* Author: KoffeinFlummi
|
|
|
|
* Calculates the offsets for all weapons needed to hit the current target.
|
|
|
|
*
|
|
|
|
* Arguments:
|
2015-12-10 15:00:14 +00:00
|
|
|
* 0: Vehicle <OBJECT>
|
|
|
|
* 1: Turret <ARRAY>
|
2015-01-11 16:42:31 +00:00
|
|
|
*
|
|
|
|
* Return Value:
|
2015-12-10 15:00:14 +00:00
|
|
|
* None
|
|
|
|
*
|
2017-06-08 13:31:51 +00:00
|
|
|
* Example:
|
|
|
|
* [car, [turret]] call ace_fcs_fnc_keyUp
|
|
|
|
*
|
2015-12-10 15:00:14 +00:00
|
|
|
* Public: No
|
2015-01-11 16:42:31 +00:00
|
|
|
*/
|
2015-01-12 10:02:44 +00:00
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
params ["_vehicle", "_turret", "_distance", ["_showHint", false], ["_playSound", true]];
|
2016-05-20 02:39:15 +00:00
|
|
|
TRACE_5("params",_vehicle,_turret,_distance,_showHint,_playSound);
|
2015-02-04 02:20:55 +00:00
|
|
|
|
2021-02-18 18:58:08 +00:00
|
|
|
private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath);
|
2015-02-04 02:20:55 +00:00
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
if (isNil "_distance") then {
|
2016-01-19 23:10:27 +00:00
|
|
|
_distance = [
|
|
|
|
getNumber (_turretConfig >> QGVAR(DistanceInterval)),
|
|
|
|
getNumber (_turretConfig >> QGVAR(MaxDistance)),
|
|
|
|
getNumber (_turretConfig >> QGVAR(MinDistance))
|
|
|
|
] call FUNC(getRange);
|
2016-05-20 02:50:51 +00:00
|
|
|
} else {
|
|
|
|
((uiNamespace getVariable ["ACE_dlgRangefinder", displayNull]) displayCtrl 1713151) ctrlSetText ([_distance, 4, 0] call CBA_fnc_formatNumber);
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
|
|
|
|
2016-01-21 01:02:50 +00:00
|
|
|
// MOVING TARGETS
|
2015-12-10 15:00:14 +00:00
|
|
|
private _weapon = _vehicle currentWeaponTurret _turret;
|
|
|
|
private _weaponDirection = _vehicle weaponDirection _weapon; // @todo doesn't work for sub turrets
|
2015-02-11 19:59:41 +00:00
|
|
|
|
2015-03-25 22:03:45 +00:00
|
|
|
if (_turret isEqualTo ([_vehicle] call EFUNC(common,getTurretCommander))) then {
|
2015-02-11 19:59:41 +00:00
|
|
|
_weaponDirection = eyeDirection _vehicle;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (_weaponDirection isEqualTo [0,0,0]) then { // dummy value for non main turrets
|
|
|
|
_weaponDirection = [1,0,0];
|
|
|
|
};
|
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
private _angleTarget = asin (_weaponDirection select 2);
|
2015-02-03 22:03:43 +00:00
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
private _movingAzimuth = 0;
|
|
|
|
|
2016-03-02 10:01:39 +00:00
|
|
|
if (CBA_missionTime - GVAR(time) > 1 && GVAR(time) != -1 && isNil {_this select 2}) then {
|
2015-01-14 20:07:41 +00:00
|
|
|
// calculate speed of target
|
2015-12-10 15:00:14 +00:00
|
|
|
private _posTarget = (getPosASL _vehicle) vectorAdd (_weaponDirection vectorMultiply _distance);
|
2016-03-02 10:01:39 +00:00
|
|
|
private _velocityTarget = (_posTarget vectorDiff GVAR(position)) vectorMultiply (1 / (CBA_missionTime - GVAR(time)));
|
2015-02-03 22:03:43 +00:00
|
|
|
|
2015-10-21 20:52:21 +00:00
|
|
|
// estimate time to target
|
2015-12-10 15:00:14 +00:00
|
|
|
private _magazine = _vehicle currentMagazineTurret _turret;
|
|
|
|
private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo");
|
|
|
|
private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
|
|
|
|
private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction");
|
|
|
|
private _timeToLive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "timeToLive");
|
|
|
|
private _simulationStep = getNumber (configFile >> "CfgAmmo" >> _ammo >> "simulationStep");
|
|
|
|
private _initSpeedCoef = getNumber (configFile >> "CfgWeapons" >> _weapon >> "initSpeed");
|
2016-01-21 13:44:23 +00:00
|
|
|
private _simulationType = getText (configFile >> "CfgAmmo" >> _ammo >> "simulation");
|
2015-12-10 15:00:14 +00:00
|
|
|
|
2016-01-21 01:02:50 +00:00
|
|
|
// More BIS fix
|
|
|
|
if (_simulationType == "shotBullet") then {
|
|
|
|
if (_initSpeedCoef < 0) then {
|
|
|
|
_initSpeed = _initSpeed * - _initSpeedCoef;
|
|
|
|
};
|
2015-12-10 15:00:14 +00:00
|
|
|
|
2016-01-21 01:02:50 +00:00
|
|
|
if (_initSpeedCoef > 0) then {
|
|
|
|
_initSpeed = _initSpeedCoef;
|
|
|
|
};
|
2015-05-01 16:55:44 +00:00
|
|
|
};
|
2015-10-21 20:17:28 +00:00
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
if (_simulationStep != 0) then {
|
2015-12-10 15:00:14 +00:00
|
|
|
private _posX = 0;
|
|
|
|
private _velocityX = _initSpeed;
|
|
|
|
private _velocityY = 0;
|
|
|
|
private _timeToTarget = 0;
|
2015-02-03 22:03:43 +00:00
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
for "_i" from 1 to (floor (_timeToLive / _simulationStep) + 1) do {
|
2015-01-14 20:07:41 +00:00
|
|
|
_posX = _posX + _velocityX * _simulationStep;
|
2015-12-10 15:00:14 +00:00
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
if (_posX >= _distance) exitWith { // bullet passed the target
|
|
|
|
_timeToTarget = _i * _simulationStep;
|
|
|
|
};
|
2015-12-10 15:00:14 +00:00
|
|
|
|
|
|
|
private _velocityMagnitude = sqrt (_velocityX ^ 2 + _velocityY ^ 2);
|
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
_velocityX = _velocityX + _velocityX * _velocityMagnitude * _airFriction * _simulationStep;
|
|
|
|
_velocityY = _velocityY + _velocityY * _velocityMagnitude * _airFriction * _simulationStep - 9.81 * _simulationStep;
|
|
|
|
};
|
|
|
|
|
|
|
|
// calculate offsets
|
2015-12-10 15:00:14 +00:00
|
|
|
private _posArrival = _posTarget vectorAdd (_velocityTarget vectorMultiply _timeToTarget);
|
|
|
|
private _dirArrival = (_posArrival vectorDiff getPosASL _vehicle) vectorMultiply (1 / (_posArrival vectorDistance getPosASL _vehicle));
|
2015-01-14 20:07:41 +00:00
|
|
|
|
|
|
|
_movingAzimuth = ((_dirArrival select 0) atan2 (_dirArrival select 1)) - ((_weaponDirection select 0) atan2 (_weaponDirection select 1));
|
|
|
|
_angleTarget = asin (_dirArrival select 2);
|
2015-12-10 15:00:14 +00:00
|
|
|
_distance = floor (_posArrival distance (getPosASL _vehicle));
|
2015-01-14 20:07:41 +00:00
|
|
|
};
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
2015-12-10 15:00:14 +00:00
|
|
|
|
2015-01-12 10:02:44 +00:00
|
|
|
GVAR(enabled) = false;
|
2015-10-21 20:17:28 +00:00
|
|
|
GVAR(time) = -1;
|
2015-01-11 16:42:31 +00:00
|
|
|
|
|
|
|
// CALCULATE AZIMUTH CORRECTION
|
2015-12-10 15:00:14 +00:00
|
|
|
private _viewDiff = _vehicle getVariable format ["%1_%2", QGVAR(ViewDiff), _turret];
|
|
|
|
private _FCSAzimuth = _movingAzimuth;
|
2015-02-03 22:03:43 +00:00
|
|
|
|
2015-01-11 16:42:31 +00:00
|
|
|
if (_viewDiff != 0) then {
|
2015-01-14 20:07:41 +00:00
|
|
|
_FCSAzimuth = (atan (_distance / _viewDiff) - (abs _viewDiff / _viewDiff) * 90) + _movingAzimuth;
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
[_vehicle, format ["%1_%2", QGVAR(Azimuth), _turret], _FCSAzimuth] call EFUNC(common,setVariablePublic);
|
2015-04-06 21:57:07 +00:00
|
|
|
|
2016-01-21 01:02:50 +00:00
|
|
|
// CALCULATE SOLUTION
|
|
|
|
[_vehicle,_turret,_distance,_angleTarget] call FUNC(calculateSolution);
|
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
if (_playSound) then {
|
2015-04-06 21:57:07 +00:00
|
|
|
playSound "ACE_Sound_Click";
|
|
|
|
};
|
|
|
|
|
2015-12-10 15:00:14 +00:00
|
|
|
if (_showHint) then {
|
2015-05-28 19:59:04 +00:00
|
|
|
[format ["%1: %2", localize LSTRING(ZeroedTo), _distance]] call EFUNC(common,displayTextStructured);
|
2015-10-21 20:17:28 +00:00
|
|
|
};
|