mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
141 lines
4.8 KiB
Plaintext
141 lines
4.8 KiB
Plaintext
|
scriptName format ["%1ARTY\data\scripts\ARTY_tof.sqf (_this: %1)",_this];
|
||
|
// ARTY_firingSolution.sqf
|
||
|
//
|
||
|
// Use the ballistics table to calculate a firing solution
|
||
|
|
||
|
#define GETELEV(T,I) ((##T## select ##I##) select 0)
|
||
|
#define GETMAXHEIGHT(T,I) ((##T## select ##I##) select 1)
|
||
|
#define GETSLICES(T,I) ((##T## select ##I##) select 2)
|
||
|
|
||
|
// Rocket ballistics values
|
||
|
#define GETOFFSETH(T,I) ((##T## select ##I##) select 3)
|
||
|
#define GETOFFSETV(T,I) ((##T## select ##I##) select 4)
|
||
|
#define GETDECAYELEV(T,I) ((##T## select ##I##) select 5)
|
||
|
#define GETDECAYSPD(T,I) ((##T## select ##I##) select 6)
|
||
|
|
||
|
private ["_firingPos", "_targetPos", "_btab", "_position", "_btab", "_i", "_sliceN", "_sliceNN", "_hmin", "_hmax", "_hstep", "_deltaX", "_deltaY", "_fs"];
|
||
|
|
||
|
_deltaX = _this select 0;
|
||
|
_deltaY = _this select 1;
|
||
|
_ballistics = _this select 2;
|
||
|
|
||
|
_btab = _ballistics select 0;
|
||
|
_minRange = _ballistics select 1;
|
||
|
_maxRange = _ballistics select 2;
|
||
|
_hmin = _ballistics select 3;
|
||
|
_hmax = _ballistics select 4;
|
||
|
_hstep = _ballistics select 5;
|
||
|
|
||
|
// Blank fs to return if there is an error (i.e. out of range)
|
||
|
_blank = [];
|
||
|
|
||
|
// _deltaX = [_firingPos select 0, _firingPos select 1, 0] distance [_targetPos select 0, _targetPos select 1, 0];
|
||
|
// _deltaY = (_targetPos select 2) - (_firingPos select 2);
|
||
|
|
||
|
// Out of range if height deltaY exceeds height differential in either direction.
|
||
|
if (_deltaY < _hmin || _deltaY > _hmax) exitWith {
|
||
|
if (BIS_ARTY_DEBUG==1) then {textLogFormat ["dY of %1 exceeds vertical range of artillery.", _deltaY];};
|
||
|
_blank
|
||
|
};
|
||
|
|
||
|
_hrange = _hmax - _hmin;
|
||
|
_colL = floor((_deltaY - _hmin)/_hstep);
|
||
|
_colH = ceil((_deltaY - _hmin)/_hstep);
|
||
|
|
||
|
// deltaY is on a boundary
|
||
|
if (_colL == _colH) then {_colH = _colH + 1};
|
||
|
|
||
|
_muY = ((_deltaY - _hmin) - _colL*_hstep) / (_colH*_hstep - _colL*_hstep);
|
||
|
|
||
|
_distN = 9999999;
|
||
|
_rowN = -1;
|
||
|
_rowNN = -1;
|
||
|
for [{_i=1},{_i < ((count _btab) - 1)},{_i=_i+1}] do
|
||
|
{
|
||
|
_prevSliceCount = count (GETSLICES(_btab, _i-1)); // Enforce boundary conditions that will come in when picking NN
|
||
|
_slices = GETSLICES(_btab, _i);
|
||
|
_nextSliceCount = count (GETSLICES(_btab, _i+1));
|
||
|
if ((count _slices) > _colH &&
|
||
|
_prevSliceCount > _colH &&
|
||
|
_nextSliceCount > _colH) then
|
||
|
{
|
||
|
_v1 = _slices select _colL; // Select data vectors
|
||
|
_v2 = _slices select _colH;
|
||
|
_testVec = [[_v1 select 0], [_v2 select 0], _muY] call BIS_ARTY_VEC_LERP; // Interpolate
|
||
|
_testDist = _testVec select 0;
|
||
|
|
||
|
if (abs(_testDist - _deltaX) < _distN) then
|
||
|
{
|
||
|
_distN = abs(_testDist - _deltaX);
|
||
|
_rowN = _i;
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
// Select nearest neighbor.
|
||
|
_n1 = GETSLICES(_btab,_rowN-1);
|
||
|
_v11 = _n1 select _colL;
|
||
|
_v12 = _n1 select _colH;
|
||
|
_n2 = GETSLICES(_btab,_rowN+1);;
|
||
|
_v21 = _n2 select _colL;
|
||
|
_v22 = _n2 select _colH;
|
||
|
_s1 = [_v11, _v12, _muY] call BIS_ARTY_VEC_LERP;
|
||
|
_s2 = [_v21, _v22, _muY] call BIS_ARTY_VEC_LERP;
|
||
|
|
||
|
_d1 = _s1 select 0;
|
||
|
_d2 = _s2 select 0;
|
||
|
if (abs(_d1 - _deltaX) < abs(_d2 - _deltaX)) then
|
||
|
{
|
||
|
_rowNN = (_rowN - 1);
|
||
|
_sliceNN = _s1;
|
||
|
} else {
|
||
|
_rowNN = (_rowN + 1);
|
||
|
_sliceNN = _s2;
|
||
|
};
|
||
|
|
||
|
// Check out of range condition in the horizontal
|
||
|
if ((_deltaX < _d1 && _deltaX < _d2) ||
|
||
|
(_deltaX > _d1 && _deltaX > _d2)) exitWith {
|
||
|
if (BIS_ARTY_DEBUG==1) then {textLogFormat ["dY = %1, dX = %2 out of firing envelope.", _deltaY, _deltaX];};
|
||
|
_blank
|
||
|
};
|
||
|
|
||
|
_n0 = GETSLICES(_btab,_rowN);
|
||
|
_v1 = _n0 select _colL;
|
||
|
_v2 = _n0 select _colH;
|
||
|
_sliceN = [_v1, _v2, _muY] call BIS_ARTY_VEC_LERP;
|
||
|
|
||
|
_elevN = GETELEV(_btab,_rowN);
|
||
|
_elevNN = GETELEV(_btab,_rowNN);
|
||
|
|
||
|
_muX = (_deltaX - (_sliceN select 0)) / ((_sliceNN select 0) - (_sliceN select 0));
|
||
|
|
||
|
// Check the type of ballistics table being worked with (single or rocket)
|
||
|
if (count (_btab select 0) >= 7) then
|
||
|
{
|
||
|
// Load rocket parameters
|
||
|
_offHN = GETOFFSETH(_btab,_rowN);
|
||
|
_offVN = GETOFFSETV(_btab,_rowN);
|
||
|
_decayElevN = GETDECAYELEV(_btab,_rowN);
|
||
|
_decaySpdN = GETDECAYSPD(_btab,_rowN);
|
||
|
_offHNN = GETOFFSETH(_btab,_rowNN);
|
||
|
_offVNN = GETOFFSETV(_btab,_rowNN);
|
||
|
_decayElevNN = GETDECAYELEV(_btab,_rowNN);
|
||
|
_decaySpdNN = GETDECAYSPD(_btab,_rowNN);
|
||
|
|
||
|
// Rocket-based firing solution.
|
||
|
_fs = [[_elevN, (_sliceN select 0), (_sliceN select 2), (_sliceN select 1), _offHN, _offVN, _decayElevN, _decaySpdN],
|
||
|
[_elevNN, (_sliceNN select 0), (_sliceNN select 2), (_sliceNN select 1), _offHNN, _offVNN, _decayElevNN, _decaySpdNN],
|
||
|
_muX] call BIS_ARTY_VEC_LERP;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Single projectile firing solution.
|
||
|
_fs = [[_elevN, (_sliceN select 0), (_sliceN select 2), (_sliceN select 1), (_sliceN select 3), (_sliceN select 4)],
|
||
|
[_elevNN, (_sliceNN select 0), (_sliceNN select 2), (_sliceNN select 1), (_sliceNN select 3), (_sliceNN select 4)],
|
||
|
_muX] call BIS_ARTY_VEC_LERP;
|
||
|
};
|
||
|
|
||
|
_fs
|
||
|
|