2015-01-11 16:42:31 +00:00
|
|
|
/*
|
|
|
|
* Author: KoffeinFlummi
|
|
|
|
*
|
|
|
|
* Calculates the offsets for all weapons needed to hit the current target.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* 0: The vehicle
|
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
* none
|
|
|
|
*/
|
|
|
|
|
2015-01-12 10:02:44 +00:00
|
|
|
#include "script_component.hpp"
|
|
|
|
|
2015-04-06 21:57:07 +00:00
|
|
|
private ["_vehicle", "_turret", "_turretConfig", "_distance", "_magazines", "_showHint", "_playSound"];
|
2015-01-11 16:42:31 +00:00
|
|
|
|
|
|
|
_vehicle = _this select 0;
|
2015-02-04 02:20:55 +00:00
|
|
|
_turret = _this select 1;
|
|
|
|
|
|
|
|
_turretConfig = [configFile >> "CfgVehicles" >> typeOf _vehicle, _turret] call EFUNC(common,getTurretConfigPath);
|
|
|
|
|
2015-01-13 21:51:02 +00:00
|
|
|
_distance = call FUNC(getRange);
|
|
|
|
|
2015-02-11 19:59:41 +00:00
|
|
|
_magazines = _vehicle magazinesTurret _turret;
|
2015-01-11 16:42:31 +00:00
|
|
|
|
|
|
|
if (_distance == 0) then {
|
2015-01-14 20:07:41 +00:00
|
|
|
_distance = [
|
2015-02-04 02:20:55 +00:00
|
|
|
getNumber (_turretConfig >> QGVAR(DistanceInterval)),
|
|
|
|
getNumber (_turretConfig >> QGVAR(MaxDistance)),
|
|
|
|
getNumber (_turretConfig >> QGVAR(MinDistance))
|
2015-01-14 20:07:41 +00:00
|
|
|
] call EFUNC(common,getTargetDistance); // maximum distance: 5000m, 5m precision
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
|
|
|
|
2015-05-01 14:24:16 +00:00
|
|
|
private ["_weapon", "_weaponDirection", "_angleTarget"];
|
|
|
|
_weapon = _vehicle currentWeaponTurret _turret;
|
|
|
|
_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-01-11 16:42:31 +00:00
|
|
|
_angleTarget = asin (_weaponDirection select 2);
|
|
|
|
|
|
|
|
if (count _this > 2) then {
|
2015-04-03 16:49:41 +00:00
|
|
|
if((_this select 2) > -1) then {
|
|
|
|
_distance = _this select 2;
|
|
|
|
};
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
|
|
|
|
2015-01-12 10:02:44 +00:00
|
|
|
if (!(isNil QGVAR(backgroundCalculation)) and {!(scriptDone GVAR(backgroundCalculation))}) then {
|
2015-01-14 20:07:41 +00:00
|
|
|
terminate GVAR(backgroundCalculation);
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
|
|
|
|
2015-02-03 22:03:43 +00:00
|
|
|
private "_movingAzimuth";
|
|
|
|
|
2015-01-11 16:42:31 +00:00
|
|
|
// MOVING TARGETS
|
|
|
|
_movingAzimuth = 0;
|
2015-01-12 10:02:44 +00:00
|
|
|
if (time - GVAR(time) > 1 and GVAR(time) != -1 and count _this < 3) then {
|
2015-01-14 20:07:41 +00:00
|
|
|
// 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)
|
2015-01-11 16:42:31 +00:00
|
|
|
];
|
2015-01-14 20:07:41 +00:00
|
|
|
_velocityTarget = [
|
|
|
|
((_posTarget select 0) - (GVAR(position) select 0)) / (time - GVAR(time)),
|
|
|
|
((_posTarget select 1) - (GVAR(position) select 1)) / (time - GVAR(time)),
|
|
|
|
((_posTarget select 2) - (GVAR(position) select 2)) / (time - GVAR(time))
|
2015-01-11 16:42:31 +00:00
|
|
|
];
|
|
|
|
|
2015-02-03 22:03:43 +00:00
|
|
|
private ["_magazineType", "_ammoType", "_initSpeed", "_airFriction", "_timeToLive", "_simulationStep"];
|
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
// estimate time to target
|
2015-02-04 02:20:55 +00:00
|
|
|
_magazineType = _vehicle currentMagazineTurret _turret;
|
2015-01-14 20:07:41 +00:00
|
|
|
_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");
|
|
|
|
|
2015-05-01 14:24:16 +00:00
|
|
|
_initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed");
|
2015-05-01 14:02:34 +00:00
|
|
|
if (_initSpeedCoef < 0) then {
|
|
|
|
_initSpeed = _initSpeed * -_initSpeedCoef;
|
|
|
|
};
|
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
if (_simulationStep != 0) then {
|
2015-02-03 22:03:43 +00:00
|
|
|
private ["_posX", "_velocityX", "_velocityY", "_timeToTarget"];
|
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
_posX = 0;
|
|
|
|
_velocityX = _initSpeed;
|
|
|
|
_velocityY = 0;
|
|
|
|
_timeToTarget = 0;
|
2015-02-03 22:03:43 +00:00
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2015-02-03 22:03:43 +00:00
|
|
|
private ["_posArrival", "_dirArrival"];
|
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
// calculate offsets
|
|
|
|
_posArrival = [
|
|
|
|
(_posTarget select 0) + (_velocityTarget select 0) * _timeToTarget,
|
|
|
|
(_posTarget select 1) + (_velocityTarget select 1) * _timeToTarget,
|
|
|
|
(_posTarget select 2) + (_velocityTarget select 2) * _timeToTarget
|
|
|
|
];
|
2015-02-03 22:03:43 +00:00
|
|
|
|
2015-01-14 20:07:41 +00:00
|
|
|
_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));
|
|
|
|
};
|
2015-01-11 16:42:31 +00:00
|
|
|
};
|
2015-01-12 10:02:44 +00:00
|
|
|
GVAR(enabled) = false;
|
|
|
|
GVAR(time) = -1;
|
2015-01-11 16:42:31 +00:00
|
|
|
|
2015-02-03 22:03:43 +00:00
|
|
|
private ["_viewDiff", "_FCSAzimuth", "_FCSMagazines", "_FCSElevation"];
|
|
|
|
|
2015-01-11 16:42:31 +00:00
|
|
|
// CALCULATE AZIMUTH CORRECTION
|
2015-02-04 02:20:55 +00:00
|
|
|
_viewDiff = _vehicle getVariable format ["%1_%2", QGVAR(ViewDiff), _turret];
|
2015-01-11 16:42:31 +00:00
|
|
|
_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-01-16 23:09:19 +00:00
|
|
|
// CALCULATE OFFSET
|
2015-01-11 16:42:31 +00:00
|
|
|
_FCSMagazines = [];
|
|
|
|
_FCSElevation = [];
|
|
|
|
|
2015-01-16 23:09:19 +00:00
|
|
|
{
|
2015-02-03 22:03:43 +00:00
|
|
|
private "_ammoType";
|
|
|
|
|
|
|
|
_ammoType = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
|
|
|
|
2015-01-16 23:09:19 +00:00
|
|
|
if !(getText (configFile >> "CfgAmmo" >> _ammoType >> "simulation") == "shotMissile") then {
|
2015-02-03 22:03:43 +00:00
|
|
|
private ["_maxElev", "_initSpeed", "_airFriction", "_offset"];
|
|
|
|
|
2015-02-04 02:20:55 +00:00
|
|
|
_maxElev = getNumber (_turretConfig >> "maxElev");
|
2015-02-03 22:03:43 +00:00
|
|
|
_initSpeed = getNumber (configFile >> "CfgMagazines" >> _x >> "initSpeed");
|
|
|
|
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammoType >> "airFriction");
|
2015-05-01 14:02:34 +00:00
|
|
|
|
2015-05-01 14:24:16 +00:00
|
|
|
_initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed");
|
2015-05-01 14:02:34 +00:00
|
|
|
if (_initSpeedCoef < 0) then {
|
|
|
|
_initSpeed = _initSpeed * -_initSpeedCoef;
|
|
|
|
};
|
|
|
|
|
2015-01-16 23:09:19 +00:00
|
|
|
_offset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, _angleTarget, _distance];
|
|
|
|
_offset = parseNumber _offset;
|
2015-01-11 16:42:31 +00:00
|
|
|
|
2015-01-16 23:09:19 +00:00
|
|
|
_FCSMagazines = _FCSMagazines + [_x];
|
|
|
|
_FCSElevation = _FCSElevation + [_offset];
|
|
|
|
};
|
|
|
|
} forEach _magazines;
|
2015-01-11 16:42:31 +00:00
|
|
|
|
2015-02-14 04:05:02 +00:00
|
|
|
[_vehicle, format ["%1_%2", QGVAR(Distance), _turret], _distance] call EFUNC(common,setVariablePublic);
|
|
|
|
[_vehicle, format ["%1_%2", QGVAR(Magazines), _turret], _FCSMagazines] call EFUNC(common,setVariablePublic);
|
|
|
|
[_vehicle, format ["%1_%2", QGVAR(Elevation), _turret], _FCSElevation] call EFUNC(common,setVariablePublic);
|
|
|
|
[_vehicle, format ["%1_%2", QGVAR(Azimuth), _turret], _FCSAzimuth] call EFUNC(common,setVariablePublic);
|
2015-01-11 16:42:31 +00:00
|
|
|
|
2015-04-06 21:57:07 +00:00
|
|
|
_showHint = false;
|
2015-04-03 16:49:41 +00:00
|
|
|
if( (count _this) > 3) then {
|
2015-04-06 21:57:07 +00:00
|
|
|
_showHint = _this select 3;
|
2015-04-03 16:49:41 +00:00
|
|
|
};
|
|
|
|
|
2015-04-06 21:57:07 +00:00
|
|
|
_playSound = true;
|
|
|
|
if( (count _this) > 3) then {
|
|
|
|
_playSound = _this select 4;
|
|
|
|
};
|
|
|
|
|
|
|
|
if(_playSound) then {
|
|
|
|
playSound "ACE_Sound_Click";
|
|
|
|
};
|
|
|
|
|
|
|
|
if(_showHint) then {
|
2015-04-03 16:49:41 +00:00
|
|
|
[format ["%1: %2", localize "STR_ACE_FCS_ZeroedTo", _distance]] call EFUNC(common,displayTextStructured);
|
|
|
|
};
|