- improve compat with a3 mlrs with remote cam (animationSourcePhase)
- handle non [0] turrets (rhs prp)
- add config entries
- use vectorCos to fix fp error (thanks commy)
This commit is contained in:
PabstMirror 2019-03-15 17:37:13 -05:00
parent 429c11ed19
commit c6d7df3770
6 changed files with 103 additions and 57 deletions

View File

@ -16,11 +16,15 @@
[{ // add a frame later to allow other modules to set variables
["LandVehicle", "init", {
params ["_vehicle"];
private _enabled = _vehicle getVariable [QGVAR(enabled), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "artilleryScanner")];
if (_enabled in [0, false]) exitWith {};
if (1 == getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> QGVAR(skipCorrections))) exitWith {};
TRACE_3("enabled",_vehicle,typeOf _vehicle,_enabled);
private _vehicleCfg = configFile >> "CfgVehicles" >> typeOf _vehicle;
// config "ace_artillerytables_applyCorrections" [0 disabled, 1 enabled] falls back to artilleryScanner
private _applyCorrections = if (isNumber (_vehicleCfg >> QGVAR(applyCorrections))) then {
getNumber (_vehicleCfg >> QGVAR(applyCorrections))
} else {
getNumber (_vehicleCfg >> "artilleryScanner")
};
if (_applyCorrections != 1) exitWith {};
TRACE_2("adding firedEH",_vehicle,configName _vehicleCfg);
_vehicle addEventHandler ["Fired", {call FUNC(firedEH)}];
}, true, [], true] call CBA_fnc_addClassEventHandler;
}, []] call CBA_fnc_execNextFrame;

View File

@ -7,9 +7,9 @@ INFO("showing shot info");
((velocity _proj) call CBA_fnc_vect2Polar) params ["_mag", "_dir", "_elev"];
private _shootPos = getPosASL _shooter;
if (_dir < 0) then {_dir = _dir + 360;};
hintSilent format ["%1 m/s\nAz: %2 [%3]\nEl: %4 [%5]\nError: %6",_mag toFixed 1, _dir toFixed 2, ((6400 / 360) * _dir) toFixed 0, _elev toFixed 2, ((6400 / 360) * _elev) toFixed 0,
_elev - (missionNamespace getVariable [QGVAR(prediction), 0])];
TRACE_1("elev offset",_elev - GVAR(prediction));
hintSilent format ["%1 m/s\nAz: %2 [%3]\nEl: %4 [%5]\nError: %6",_mag toFixed 1, _dir toFixed 2, ((6400 / 360) * _dir) toFixed 0, _elev toFixed 2, ((6400 / 360) * _elev) toFixed 0,
_elev - (missionNamespace getVariable [QGVAR(predictedElevation), 0])];
TRACE_1("elev offset",_elev - GVAR(predictedElevation));
private _submunitionAmmo = getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo");
[{

View File

@ -24,31 +24,60 @@ if (_menuType != 1) exitWith {};
private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []];
private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []];
TRACE_2("",_vehicleAdded,_rangeTablesShown);
TRACE_2("searching for new vehicles",_vehicleAdded,_rangeTablesShown);
{
private _vehicle = _x;
private _typeOf = typeOf _vehicle;
private _enabled = _vehicle getVariable [QGVAR(enabled), getNumber (configFile >> "CfgVehicles" >> _typeOf >> "artilleryScanner")];
TRACE_3("",_vehicle,_typeOf,_enabled);
private _vehicleCfg = configFile >> "CfgVehicles" >> typeOf _x;
// config "ace_artillerytables_showRangetable" [0 disabled, 1 enabled] falls back to artilleryScanner
private _showRangetable = if (isNumber (_vehicleCfg >> QGVAR(showRangetable))) then {
getNumber (_vehicleCfg >> QGVAR(showRangetable))
} else {
getNumber (_vehicleCfg >> "artilleryScanner")
};
if ((_showRangetable == 1) && {!(_x in _vehicleAdded)}) then {
private _vehicle = _x;
private _turret = [];
private _turretCfg = configNull; // find turret with artillery, will be one with primaryGunner = 1 (e.g. RHS PRP-3)
{
private _xTurretCfg = [_vehicleCfg, _x] call CBA_fnc_getTurret;
if ((getNumber (_xTurretCfg >> "primaryGunner")) == 1) exitWith {
_turret = _x;
_turretCfg = _xTurretCfg;
};
} forEach allTurrets _vehicle;
TRACE_3("",_vehicle,configName _vehicleCfg,_turret);
if (isNull _turretCfg) exitWith { ERROR_1("no primaryGunner %1",configName _vehicleCfg); };
if ((count _turret) != 1) then { WARNING_2("sub turret %1-%2",_typeOf,_turret); };
if ((_enabled in [1,true]) && {!(_vehicle in _vehicleAdded)}) then {
private _vehicle = _vehicle;
private _weaponsTurret = _vehicle weaponsTurret [0];
private _weaponsTurret = _vehicle weaponsTurret _turret;
if ((count _weaponsTurret) != 1) exitWith { WARNING_1("multiple weapons - %1",_typeOf); };
private _weapon = _weaponsTurret select 0;
private _turretAnimBody = getText (_turretCfg >> "animationSourceBody");
private _turretAnimGun = getText (_turretCfg >> "animationSourceGun");
// For artillery with detached camera (I_Truck_02_MRL_F) need to use animationSourcePhase
// But that command won't always work, so fallback to animationPhase
private _currentElevRad = _vehicle animationSourcePhase _turretAnimGun;
if (isNil "_currentElevRad") then { _currentElevRad = _vehicle animationPhase _turretAnimGun; };
private _currentTraverseRad = _vehicle animationSourcePhase _turretAnimBody;
if (isNil "_currentTraverseRad") then { _currentTraverseRad = _vehicle animationPhase _turretAnimBody; };
// Some turrets (MK6) have a neutralX rotation that we need to add to min/max config elevation to get actual limits
private _weaponDir = _vehicle weaponDirection _weapon;
private _turretRot = [vectorDir _vehicle, vectorUp _vehicle, (180 / PI) * (_vehicle animationPhase "mainTurret")] call FUNC(rotateVector3d);
private _neutralX = acos (_turretRot vectorDotProduct _weaponDir) - (180 / PI) * (_vehicle animationPhase "mainGun");
private _turretRot = [vectorDir _vehicle, vectorUp _vehicle, (180 / PI) * _currentTraverseRad] call FUNC(rotateVector3d);
private _neutralX = (acos (_turretRot vectorCos _weaponDir)) - ((180 / PI) * _currentElevRad);
_neutralX = (round (_neutralX * 10)) / 10; // minimize floating point errors
private _turretCfg = [_typeOf, [0]] call CBA_fnc_getTurret;
private _minElev = _neutralX + getNumber (_turretCfg >> "minElev");
private _maxElev = _neutralX + getNumber (_turretCfg >> "maxElev");
private _advCorrection = GVAR(advancedCorrections) && {(getNumber (configFile >> "CfgVehicles" >> _typeOf >> QGVAR(skipCorrections))) != 1};
private _applyCorrections = if (isNumber (_vehicleCfg >> QGVAR(applyCorrections))) then {
getNumber (_vehicleCfg >> QGVAR(applyCorrections))
} else {
getNumber (_vehicleCfg >> "artilleryScanner")
};
private _advCorrection = GVAR(advancedCorrections) && {_applyCorrections == 1};
private _info = [_weapon, _minElev, _maxElev, _advCorrection]; // in case multiple vehicle types use the same weapon
@ -71,13 +100,11 @@ TRACE_2("",_vehicleAdded,_rangeTablesShown);
// && {[_player, objNull, ["notOnMap", "isNotSitting"]] call EFUNC(common,canInteractWith)}
true
};
private _displayName = format ["%1%2", getText (configFile >> "CfgVehicles" >> _typeOf >> "displayName"),["","*"] select _advCorrection];
private _displayName = format ["%1%2", getText (_vehicleCfg >> "displayName"),["","*"] select _advCorrection];
private _action = [format ['QGVAR(%1)',_index], _displayName, QPATHTOF(UI\icon_rangeTable.paa), _statement, _condition, {}, _info] call EFUNC(interact_menu,createAction);
private _ret = [ace_player, 1, ["ACE_SelfActions", "ACE_Equipment"], _action] call EFUNC(interact_menu,addActionToObject);
TRACE_1("added action",_ret);
[ace_player, 1, ["ACE_SelfActions", "ACE_Equipment"], _action] call EFUNC(interact_menu,addActionToObject);
TRACE_1("added action",_displayName);
ace_player setVariable [QGVAR(rangeTablesShown), _rangeTablesShown];
};
};
} forEach (nearestObjects [ace_player, ["LandVehicle"], 25]);

View File

@ -19,10 +19,14 @@
params ["_player", "_turret"];
private _vehicle = vehicle _player;
private _typeOf = typeOf _vehicle;
TRACE_3("turretEH",_player,_turret,_typeOf);
private _enabled = (alive _player) && {_turret isEqualTo [0]}
&& { ((_vehicle getVariable [QGVAR(enabled), getNumber (configFile >> "CfgVehicles" >> _typeOf >> "artilleryScanner")]) in [1, true])};
private _vehicleCfg = configFile >> "CfgVehicles" >> _typeOf;
// config "ace_artillerytables_showGunLaying" [0 disabled, 1 enabled, 2 enabled w/ alt elevationMode] falls back to artilleryScanner
private _showGunLaying = if (isNumber (_vehicleCfg >> QGVAR(showGunLaying))) then {
getNumber (_vehicleCfg >> QGVAR(showGunLaying))
} else {
getNumber (_vehicleCfg >> "artilleryScanner")
};
TRACE_4("turretChanged",_player,_typeOf,_turret,_showGunLaying);
if (GVAR(pfID) >= 0) then {
TRACE_1("removing pfEH and display",GVAR(pfID));
@ -33,27 +37,32 @@ if (GVAR(pfID) >= 0) then {
};
};
if (_enabled) then {
// Ugh, see FUNC(turretPFEH)
private _useAltElevation = (["Mortar_01_base_F", "rhs_2b14_82mm_Base", "RHS_M252_Base", "CUP_B_M1129_MC_MK19_Desert"] findIf {_typeOf isKindOf _x}) > -1;
if ((alive _player) && {_showGunLaying > 0} && {_player == gunner _vehicle}) then {
private _turretCfg = [_typeOf, _turret] call CBA_fnc_getTurret;
private _turretAnimBody = getText (_turretCfg >> "animationSourceBody");
// Ugh, see FUNC(turretPFEH) for why this is needed
private _useAltElevation = (_showGunLaying == 2)
|| {(["Mortar_01_base_F", "rhs_2b14_82mm_Base", "RHS_M252_Base", "CUP_B_M1129_MC_MK19_Desert"] findIf {_typeOf isKindOf _x}) > -1;};
private _weaponsTurret = _vehicle weaponsTurret _turret;
if ((count _weaponsTurret) != 1) then { WARNING_1("multiple weapons - %1",typeOf _vehicle); };
if ((count _weaponsTurret) != 1) then { WARNING_2("not singular weapon in turret - %1 - %2",_typeOf,_turret); };
private _weapon = _weaponsTurret param [0, ""];
#ifdef DEBUG_MODE_FULL
private _ballisticsComputer = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ballisticsComputer");
private _elevationMode = getNumber (([_typeOf, _turret] call CBA_fnc_getTurret) >> "elevationMode");
private _discreteDistance = getArray (([_typeOf, _turret] call CBA_fnc_getTurret) >> "discreteDistance");
TRACE_4("",_weapon,_ballisticsComputer,_elevationMode,_discreteDistance);
#endif
private _fireModes = getArray (configFile >> "CfgWeapons" >> _weapon >> "modes");
_fireModes = (_fireModes apply {configFile >> "CfgWeapons" >> _weapon >> _x}) select {1 == getNumber (_x >> "showToPlayer")};
_fireModes = _fireModes apply {[getNumber (_x >> "artilleryCharge"), configName _x]};
_fireModes sort true;
_fireModes = _fireModes apply {_x select 1};
GVAR(pfID) = [LINKFUNC(turretPFEH), 0, [_vehicle, _turret, _fireModes, _useAltElevation]] call CBA_fnc_addPerFrameHandler;
GVAR(pfID) = [LINKFUNC(turretPFEH), 0, [_vehicle, _turret, _fireModes, _useAltElevation, _turretAnimBody]] call CBA_fnc_addPerFrameHandler;
TRACE_1("added pfEH",GVAR(pfID));
#ifdef DEBUG_MODE_FULL
private _ballisticsComputer = getNumber (configFile >> "CfgWeapons" >> _weapon >> "ballisticsComputer");
private _elevationMode = getNumber (_turretCfg >> "elevationMode");
private _discreteDistance = getArray (_turretCfg >> "discreteDistance");
TRACE_4("",_weapon,_ballisticsComputer,_elevationMode,_discreteDistance);
#endif
};

View File

@ -14,7 +14,7 @@
*
* Public: No
*/
(_this select 0) params ["_mortarVeh", "_turret", "_fireModes", "_useAltElevation"];
(_this select 0) params ["_vehicle", "_turret", "_fireModes", "_useAltElevation", "_turretAnimBody"];
if (shownArtilleryComputer && {GVAR(disableArtilleryComputer)}) then {
@ -37,41 +37,45 @@ _ctrlGroup ctrlShow true;
BEGIN_COUNTER(pfeh);
private _currentFireMode = (weaponState [_mortarVeh, _turret]) select 2;
private _currentFireMode = (weaponState [_vehicle, _turret]) select 2;
private _currentChargeMode = _fireModes find _currentFireMode;
private _lookVector = (AGLtoASL (positionCameraToWorld [0,0,0])) vectorFromTo (AGLtoASL (positionCameraToWorld [0,0,1]));
private _weaponDir = _mortarVeh weaponDirection (currentWeapon _mortarVeh);
private _weaponDir = _vehicle weaponDirection (currentWeapon _vehicle);
// Calc real azimuth/elevation
// (looking at the sky VS looking at ground will radicaly change fire direction because BIS)
private _display = uiNamespace getVariable ["ACE_dlgArtillery", displayNull];
private _useRealWeaponDir = if ((isNull (_display displayCtrl 173)) || {(_mortarVeh ammo (currentWeapon _mortarVeh)) == 0}) then {
private _useRealWeaponDir = if ((isNull (_display displayCtrl 173)) || {(_vehicle ammo (currentWeapon _vehicle)) == 0}) then {
// With no ammo, distance display will be empty, but gun will still fire at wonky angle if aimed at ground
private _testSeekerPosASL = AGLtoASL (positionCameraToWorld [0,0,0]);
private _testPoint = _testSeekerPosASL vectorAdd (_lookVector vectorMultiply viewDistance);
!((terrainIntersectASL [_testSeekerPosASL, _testPoint]) || {lineIntersects [_testSeekerPosASL, _testPoint, _mortarVeh]});
!((terrainIntersectASL [_testSeekerPosASL, _testPoint]) || {lineIntersects [_testSeekerPosASL, _testPoint, _vehicle]});
} else {
((ctrlText (_display displayCtrl 173)) == "--")
};
private _realElevation = asin (_weaponDir select 2);
private _realAzimuth = if (_useRealWeaponDir) then {
private _realAzimuth = 0;
if (_useRealWeaponDir) then {
// No range (looking at sky), it will follow weaponDir:
(_weaponDir select 0) atan2 (_weaponDir select 1)
_realAzimuth = (_weaponDir select 0) atan2 (_weaponDir select 1)
} else {
// Valid range, will fire at camera dir
// Azimuth will still be look dir EVEN IF elevation has flipped over 90! (on steep hills)
_realAzimuth = ((_lookVector select 0) atan2 (_lookVector select 1));
if (_useAltElevation) then {
// Some mortars have odd launch angles... still not sure why
// Some small mortars have odd launch angles (I think due to the addition of neutral elevation constant with the manual elevation)
// This gets very close, (should be less than 0.5deg deviation on a 20deg slope)
private _turretRot = [vectorDir _mortarVeh, vectorUp _mortarVeh, (180 / PI) * (_mortarVeh animationPhase "mainTurret")] call FUNC(rotateVector3d);
private _currentTraverseRad = _vehicle animationSourcePhase _turretAnimBody;
if (isNil "_currentTraverseRad") then { _currentTraverseRad = _vehicle animationPhase _turretAnimBody; };
// Get turret roatation around it's z axis, then calc weapon elev in it's projection
private _turretRot = [vectorDir _vehicle, vectorUp _vehicle, (180 / PI) * _currentTraverseRad] call FUNC(rotateVector3d);
_realElevation = acos (_turretRot vectorDotProduct _weaponDir) + ((_turretRot call CBA_fnc_vect2polar) select 2);
if (_realElevation > 90) then { _realElevation = 180 - _realElevation; }; // does not flip azimuth!
};
((_lookVector select 0) atan2 (_lookVector select 1))
};
if (_realAzimuth < 0) then { _realAzimuth = _realAzimuth + 360; };
if (_realAzimuth < 0) then { _realAzimuth = _realAzimuth + 360; }; // mils will be 0-6400
private _ctrlCharge = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_CHARGE;
private _ctrlAzimuth = (uiNamespace getVariable [QGVAR(display), displayNull]) displayCtrl IDC_AZIMUTH;
@ -81,11 +85,13 @@ _ctrlAzimuth ctrlSetText Format ["AZ: %1", [DEGTOMILS * _realAzimuth, 4, 0] call
_ctrlElevation ctrlSetText Format ["EL: %1", [DEGTOMILS * _realElevation, 4, 0] call CBA_fnc_formatNumber];
_ctrlCharge ctrlSetText format ["CH: %1", _currentChargeMode];
GVAR(predictedAzimuth) = _realAzimuth;
GVAR(predictedElevation) = _realElevation;
END_COUNTER(pfeh);
#ifdef DEBUG_MODE_FULL
// private _lookVector = (AGLtoASL (positionCameraToWorld [0,0,0])) vectorFromTo (AGLtoASL (positionCameraToWorld [0,0,10]));
// systemChat format ["AZ: %1 EL: %2", _realAzimuth toFixed 1, _realElevation toFixed 1];
// systemChat format ["Slope: %1 - Look: %2 [%3]", (acos ((vectorUp _mortarVeh) select 2)) toFixed 1, ((_lookVector select 0) atan2 (_lookVector select 1)), ["GND","SKY"] select _useRealWeaponDir];
GVAR(prediction) = _realElevation;
// systemChat format ["Slope: %1 - Look: %2 [%3]", (acos ((vectorUp _vehicle) select 2)) toFixed 1, ((_lookVector select 0) atan2 (_lookVector select 1)), ["GND","SKY"] select _useRealWeaponDir];
#endif

View File

@ -3,7 +3,7 @@
[
QGVAR(advancedCorrections), "CHECKBOX",
[LSTRING(advancedCorrections_displayName), LSTRING(advancedCorrections_description)],
"ACE Artillery",
["ACE Artillery", QUOTE(COMPONENT_BEAUTIFIED)],
false, // default value
true, // isGlobal
{[QGVAR(advancedCorrections), _this] call EFUNC(common,cbaSettings_settingChanged)},
@ -13,7 +13,7 @@
[
QGVAR(disableArtilleryComputer), "CHECKBOX",
[LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)],
"ACE Artillery",
["ACE Artillery", QUOTE(COMPONENT_BEAUTIFIED)],
false, // default value
true, // isGlobal
{[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)},