diff --git a/description.ext b/description.ext index ee3f7db..38a7eb9 100644 --- a/description.ext +++ b/description.ext @@ -3,6 +3,7 @@ class CfgFunctions { #include "scripts\arsr\funcs.hpp" // enable sound directionfinder #include "scripts\stomper\funcs.hpp" // enable sitting on Stomper UGV #include "scripts\craters\funcs.hpp" // terrain deformation on artillery impacts + #include "scripts\easyarty\funcs.hpp" // easy azimuth and elevation calculation }; diff --git a/scripts/easyarty/funcs.hpp b/scripts/easyarty/funcs.hpp new file mode 100644 index 0000000..681eaff --- /dev/null +++ b/scripts/easyarty/funcs.hpp @@ -0,0 +1,11 @@ +class easyarty { + tag = "easyarty"; + class functions { + file = "scripts\easyarty\functions"; + class postInit{postInit = 1;}; + class setTargetPos{}; + class calculate{}; + class start{}; + class stop{}; + }; +}; diff --git a/scripts/easyarty/functions/fn_calculate.sqf b/scripts/easyarty/functions/fn_calculate.sqf new file mode 100644 index 0000000..0e4b396 --- /dev/null +++ b/scripts/easyarty/functions/fn_calculate.sqf @@ -0,0 +1,54 @@ +params ["_targetPos", "_vehicle"]; + +#define DEGREE_TO_MIL_FACTOR 17.7777777778 + +private _az = (_vehicle getDir _targetPos) * DEGREE_TO_MIL_FACTOR; + +private _deltaDistance = _vehicle distance2d _targetPos; +private _distanceRounded = _deltaDistance - _deltaDistance % 100; +private _distanceFactor = _deltaDistance % 100 * 0.01; +private _heightFactor = ((getPosASL _vehicle select 2) - getTerrainHeightASL _targetPos) / 100 * -1; + +(ace_artillerytables_magModeData select ace_artillerytables_lastCharge) params [["_muzzleVelocity", -1], ["_airFriction", 0]]; +private _elevMin = 10; +private _elevMax = 75; +private _lastElevMode = ace_artillerytables_lastElevationMode; +private _ret = "ace_artillerytables" callExtension ["start", [_muzzleVelocity,_airFriction,_elevMin,_elevMax,_lastElevMode]]; +private _status = 0; +private _result = []; + +while { _status != 3 } do { + _ret = ("ace_artillerytables" callExtension ["getline", []]); + _status = _ret select 1; + if (_status == 1) then { + _result pushBack parseSimpleArray (_ret select 0); + }; +}; + +private _resultLength = count _result; + +if (_resultLength < 3) exitWith {[]}; + +private _minResult = parseNumber (_result select 0 select 0); +private _maxResult = parseNumber (_result select _resultLength-1 select 0); + +if (_deltaDistance > _maxResult || {_deltaDistance < _minResult}) exitWith { [] }; + +private _idxLower = (_distanceRounded - _minResult) / 100; +private _idxUpper = (_distanceRounded + 100 - _minResult) / 100; + +private _lSolution = _result select _idxLower; +private _uSolution = _result select _idxUpper; + +private _diffElevation = parseNumber (_lSolution select 1) - parseNumber (_uSolution select 1); +private _hightOffset = _lSolution select 2; +_hightOffset = [1, parseNumber _hightOffset] select (_hightOffset isNotEqualTo "-"); + +private _tof = _lSolution select 4; + +// in high mode less elevation is father, in low it is the opposite. +// in high mode we subtract to gain range, in low mode we need to add +// because - * a negative number (see diff calc) is like adding, this works for both cases +private _finalElevation = parseNumber (_lSolution select 1) - _diffElevation * _distanceFactor - _hightOffset * _heightFactor; + +[_finalElevation, _az, _deltaDistance, _tof]; \ No newline at end of file diff --git a/scripts/easyarty/functions/fn_postInit.sqf b/scripts/easyarty/functions/fn_postInit.sqf new file mode 100644 index 0000000..a5ae7d7 --- /dev/null +++ b/scripts/easyarty/functions/fn_postInit.sqf @@ -0,0 +1,69 @@ +if !(hasinterface) exitWith {}; + +easyarty_running = false; +easyarty_pfh = -1; +easyarty_displayEh = -1; + +private _spacerAction = [ + "easyarty_spacer", + "Easy Arty", + "", + {}, + {[player, "ACE_artilleryTable"] call BIS_fnc_hasItem} +] call ace_interact_menu_fnc_createAction; + +private _startAction = [ + "easyarty_start", + "Start calculate", + "", + {[] spawn easyarty_fnc_start;}, + {!easyarty_running} +] call ace_interact_menu_fnc_createAction; + +private _stopAction = [ + "easyarty_stop", + "Stop calculation", + "", + {[] call easyarty_fnc_stop;}, + {easyarty_running} +] call ace_interact_menu_fnc_createAction; + +private _newTargetAction = [ + "easyarty_newTarget", + "Assign new target", + "", + {[] spawn easyarty_fnc_setTargetPos;}, + {easyarty_running} +] call ace_interact_menu_fnc_createAction; + +[ + "Man", + 1, + ["ACE_SelfActions"], + _spacerAction, + true +] call ace_interact_menu_fnc_addActionToClass; + +[ + "Man", + 1, + ["ACE_SelfActions", "easyarty_spacer"], + _startAction, + true +] call ace_interact_menu_fnc_addActionToClass; + +[ + "Man", + 1, + ["ACE_SelfActions", "easyarty_spacer"], + _stopAction, + true +] call ace_interact_menu_fnc_addActionToClass; + +[ + "Man", + 1, + ["ACE_SelfActions", "easyarty_spacer"], + _newTargetAction, + true +] call ace_interact_menu_fnc_addActionToClass; diff --git a/scripts/easyarty/functions/fn_setTargetPos.sqf b/scripts/easyarty/functions/fn_setTargetPos.sqf new file mode 100644 index 0000000..8155397 --- /dev/null +++ b/scripts/easyarty/functions/fn_setTargetPos.sqf @@ -0,0 +1,17 @@ +openMap [true, true]; + +hint "Click on the map to place a target"; + +private _mapClickEh = addMissionEventHandler ["MapSingleClick", { + params ["", "_pos"]; + deleteMarkerLocal "target_loc"; + private _marker = createMarkerLocal ["target_loc", _pos]; + _marker setMarkerTypeLocal "HD_DOT"; + _marker setMarkerTextLocal "Target"; + easyarty_target = _pos; + openMap [false, false]; +}]; + +waitUntil {!visibleMap}; + +removeMissionEventHandler ["MapSingleClick", _mapClickEh] \ No newline at end of file diff --git a/scripts/easyarty/functions/fn_start.sqf b/scripts/easyarty/functions/fn_start.sqf new file mode 100644 index 0000000..9d1bc20 --- /dev/null +++ b/scripts/easyarty/functions/fn_start.sqf @@ -0,0 +1,28 @@ +if (easyarty_running) exitWith {}; +if (isNil "ace_artillerytables_magModeData") exitWith { hint "You must have chosen an artillery solution!" }; + +call easyarty_fnc_setTargetPos; + +easyarty_displayEh = (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw", { + (_this select 0) drawLine [ + getPos player, + easyarty_target, + [0,0,1,1] + ]; +}]; + +easyarty_pfh = [{ + private _solution = [easyarty_target, vehicle player] call easyarty_fnc_calculate; + if (_solution isEqualTo []) exitwith { + hintSilent "No solution found. Please try another range card setting!"; + }; + hintSilent format [ + "=== SOLUTION ===\nDISTANCE: %1\nTOF: %2sec\nELEVATION: %3\nAZIMUTH: %4\n", + _solution select 2, + _solution select 3, + _solution select 0, + _solution select 1 + ]; +}, 1] call CBA_fnc_addPerFrameHandler; + +easyarty_running = true; \ No newline at end of file diff --git a/scripts/easyarty/functions/fn_stop.sqf b/scripts/easyarty/functions/fn_stop.sqf new file mode 100644 index 0000000..5883331 --- /dev/null +++ b/scripts/easyarty/functions/fn_stop.sqf @@ -0,0 +1,7 @@ +if (!easyarty_running) exitWith {}; + +easyarty_pfh call CBA_fnc_removePerFrameHandler; +(findDisplay 12 displayCtrl 51) ctrlRemoveEventHandler ["Draw", easyarty_displayEh]; +deleteMarkerLocal "target_loc"; + +easyarty_running = false; \ No newline at end of file